Generic Doubly Linked-list implementation in C++
Identifiers that start with a double underscore, or a single underscore followed by a capital letter, are reserved for use by the implementation. Your use of __T could conflict with this use.
Spacing is important. The blank line between template &lt;typename __T&gt; and the following class List line makes it harder to recognize the class as a template class.
What is the purpose of the current member? It is unnecessary.
c_size should probably be std::size_t, not unsigned long long. Because it is a private typedef, users of your class cannot access the type and can only declare a variable to hold the returned value using auto.
You don't declare the copy constructor, copy assignment operator, move constructor, nor move assignment operators. This will cause problems with assignments of one List object to another.
insert_head and insert_back are very similar functions, but have been written somewhat differently. The implementation for insert_back can be made shorter by making it similar to insert_head. In particular, the assignment to new_node-&gt;prev can be done before the if (using new_node-&gt;prev = tail;, because when head is NULL, tail should also be), while the common tail = new_node; can be done after.
first, last, and size should also have the const modifier (e.g., constexpr c_size size() const.
remove_all will crash because you access current-&gt;next after delete current, nor do you delete the first (head) element.