Index: src/libcfa/bits/containers.h
===================================================================
--- src/libcfa/bits/containers.h	(revision 14a61b5e0193d16a9724adf11613922ed2eeec81)
+++ src/libcfa/bits/containers.h	(revision de94a60491c1429f478b0393f4b57a8200aee916)
@@ -191,12 +191,5 @@
 //-----------------------------------------------------------------------------
 #ifdef __cforall
-	trait is_db_node(dtype T) {
-		T*& get_next( T& );
-		T*& get_prev( T& );
-	};
-#endif
-
-#ifdef __cforall
-	forall(dtype TYPE | is_db_node(TYPE))
+	forall(dtype TYPE | sized(TYPE))
 	#define T TYPE
 #else
@@ -205,4 +198,5 @@
 struct __dllist {
 	T * head;
+	* [T * & next, T * & prev] ( T & ) __get;
 };
 #undef T
@@ -216,46 +210,51 @@
 #ifdef __cforall
 
-	forall(dtype T | is_db_node(T))
-	static inline void ?{}( __dllist(T) & this ) with( this ) {
-		head{ NULL };
-	}
-
-	// forall(dtype T | is_db_node(T) | sized(T))
-	// static inline void push_front( __dllist(T) & this, T & node ) with( this ) {
-	// 	if ( head ) {
-	// 		get_next( node ) = head;
-	// 		get_prev( node ) = get_prev( *head );
-	// 		// inserted node must be consistent before it is seen
-	// 		// prevent code movement across barrier
-	// 		asm( "" : : : "memory" );
-	// 		get_prev( *head ) = node;
-	// 		T & prev = *get_prev( node );
-	// 		get_next( prev ) = node;
-	// 	}
-	// 	else {
-	// 		get_next( node ) = &node;
-	// 		get_prev( node ) = &node;
-	// 	}
-
-	// 	// prevent code movement across barrier
-	// 	asm( "" : : : "memory" );
-	// 	head = val;
-	// }
-
-	// forall(dtype T | is_db_node(T) | sized(T))
-	// static inline T * remove( __dllist(T) & this, T & node ) with( this ) {
-	// 	if ( &node == head ) {
-	// 		if ( get_next( *head ) == head ) {
-	// 			head = NULL;
-	// 		}
-	// 		else {
-	// 			head = get_next( *head );
-	// 		}
-	// 	}
-	// 	get_prev( *get_next( node ) ) = get_prev( node );
-	// 	get_next( *get_prev( node ) ) = get_next( node );
-	// 	get_next( node ) = NULL;
-	// 	get_prev( node ) = NULL;
-	// }
+	forall(dtype T | sized(T))
+	static inline [void] ?{}( __dllist(T) & this, * [T * & next, T * & prev] ( T & ) __get ) {
+		this.head{ NULL };
+		this.__get = __get;
+	}
+
+	#define _next .0
+	#define _prev .1
+	forall(dtype T | sized(T))
+	static inline void push_front( __dllist(T) & this, T & node ) with( this ) {
+		if ( head ) {
+			__get( node )_next = head;
+			__get( node )_prev = __get( *head )_prev;
+			// inserted node must be consistent before it is seen
+			// prevent code movement across barrier
+			asm( "" : : : "memory" );
+			__get( *head )_prev = &node;
+			T & prev = *__get( node )_prev;
+			__get( prev )_next = &node;
+		}
+		else {
+			__get( node )_next = &node;
+			__get( node )_prev = &node;
+		}
+
+		// prevent code movement across barrier
+		asm( "" : : : "memory" );
+		head = &node;
+	}
+
+	forall(dtype T | sized(T))
+	static inline void remove( __dllist(T) & this, T & node ) with( this ) {
+		if ( &node == head ) {
+			if ( __get( *head )_next == head ) {
+				head = NULL;
+			}
+			else {
+				head = __get( *head )_next;
+			}
+		}
+		__get( *__get( node )_next )_prev = __get( node )_prev;
+		__get( *__get( node )_prev )_next = __get( node )_next;
+		__get( node )_next = NULL;
+		__get( node )_prev = NULL;
+	}
+	#undef _next
+	#undef _prev
 #endif
 
