pubby avatar pubby committed db4bfd4

Create non-variadic versions of left-growing lists.

Uses xmacros to generate the boilerplate.
lg_list, word, inline, and separate_scope were updated.

Comments (0)

Files changed (7)

libdir/smpl/inline.hpp

 #define SMPL_INLINE_HPP
 
 #include <libdir/smpl/list_to_inline.hpp>
-
 #include <libdir/smpl/list/list_interface.hpp>
-
 #include <libdir/smpl/vocab/id.hpp>
 
+#ifndef SMPL_LIMIT_INLINE_SIZE
+  #define SMPL_LIMIT_INLINE_SIZE 20
+#endif
+
+#include <libdir/smpl/list/impl/lg_list_prerequisites_xmacro.hpp>
+
 namespace smpl {
 
-  // smpl::inline_ composes words together similiar to smpl::word.
-  // The difference between this and smpl::word is only notable when working
-  // with continuations;
-  // smpl::word allows scoping, while smpl::inline_ does not.
-  template<typename... Words>
-  struct inline_
-  : list_to_inline< inline_<Words...> >
-  {};
-
-  namespace list {
-    
-    template<typename HeadWord, typename... TailWords>
-    struct head<inline_<HeadWord, TailWords...>> {
-      typedef
-        HeadWord
-        type;
-    };
-
-    template<typename HeadWord, typename... TailWords>
-    struct tail<inline_<HeadWord, TailWords...>> {
-      // list
-      typedef
-        inline_<TailWords...>
-        type;
-    };
-
-    template<typename Word, typename... Words>
-    struct cons<Word, inline_<Words...>> {
-      // list
-      typedef
-        inline_<Word, Words...>
-        type;
-    };
-
-    template<typename... Words>
-    struct is_empty<inline_<Words...>> {
-      static bool const value = false;
-    };
-    template<>
-    struct is_empty<inline_<>> {
-      static bool const value = true;
-    };
-
-  } // namespace list
+  // List container
+  #define SMPL_LIST_NAME inline_
+  #define SMPL_LIST_SIZE SMPL_LIMIT_INLINE_SIZE
+  #define SMPL_LIST_INHERIT(inline_) list_to_inline<inline_>
+  #define SMPL_TAG_NAME  inline_tag
+  #include <libdir/smpl/list/impl/lg_list_xmacro.hpp>
 
 } // namespace smpl
 
+// List interface
+#define SMPL_TAG_NAME ::smpl::list::inline_tag
+#include <libdir/smpl/list/impl/members_implement_xmacro.hpp>
+
 #endif // include guard
 

libdir/smpl/list/impl/lg_list_prerequisites_xmacro.hpp

+#ifndef SMPL_LIST_IMPL_LG_LIST_PREREQUISITES_XMACRO_HPP
+#define SMPL_LIST_IMPL_LG_LIST_PREREQUISITES_XMACRO_HPP
+
+#include <libdir/smpl/impl/placeholder_type.hpp>
+#include <libdir/smpl/list/list_interface.hpp>
+
+#include <boost/static_assert.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/arithmetic/sub.hpp>
+#include <boost/preprocessor/repetition/enum.hpp>
+#include <boost/preprocessor/repetition/enum_shifted.hpp>
+#include <boost/preprocessor/repetition/repeat.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+
+#endif // include guard
+

libdir/smpl/list/impl/lg_list_xmacro.hpp

+// This is an xmacro - include this file
+
+#ifndef SMPL_LIST_IMPL_LG_LIST_PREREQUISITES_XMACRO_HPP
+#error "include prerequisites before including"
+#endif
+
+#ifndef SMPL_TAG_NAME
+#error "undefined xmacro parameter: SMPL_TAG_NAME"
+#endif
+
+#ifndef SMPL_LIST_NAME
+#error "undefined xmacro parameter: SMPL_LIST_NAME"
+#endif
+
+#ifndef SMPL_LIST_SIZE
+#error "undefined xmacro parameter: SMPL_LIST_SIZE"
+#endif
+
+// Optional xmacro parameter: SMPL_LIST_INHERIT(t) where t is SMPL_LIST_NAME
+
+struct SMPL_TAG_NAME {};
+
+#ifdef BOOST_NO_VARIADIC_TEMPLATES
+
+  template<
+    #define SMPL_param(z,n,data) typename T##n=::smpl::impl::_
+      BOOST_PP_ENUM(SMPL_LIST_SIZE, SMPL_param,)
+    #undef SMPL_param
+  >
+  struct SMPL_LIST_NAME
+  #ifdef SMPL_LIST_INHERIT
+    #define SMPL_arg(z,n,data) BOOST_PP_CAT(T,n)
+      : SMPL_LIST_INHERIT(
+          SMPL_LIST_NAME<BOOST_PP_ENUM(SMPL_LIST_SIZE, SMPL_arg,)>)
+    #undef SMPL_arg
+  #endif
+  {
+    public:
+      typedef SMPL_LIST_NAME type;
+      typedef SMPL_TAG_NAME tag;
+    private:
+      struct head {
+        typedef
+          T0
+          type;
+      };
+
+      struct tail {
+        typedef
+          SMPL_LIST_NAME<
+            #define SMPL_arg(z,n,data) BOOST_PP_CAT(T,n)
+              BOOST_PP_ENUM_SHIFTED(SMPL_LIST_SIZE, SMPL_arg,)
+            #undef SMPL_arg
+            , ::smpl::impl::_
+          >
+          type;
+      };
+
+      template<typename T>
+      struct cons {
+        BOOST_STATIC_ASSERT_MSG(
+          (::boost::is_same<
+            BOOST_PP_CAT(T,
+              BOOST_PP_SUB(SMPL_LIST_SIZE,1)),
+            ::smpl::impl::_ >::value),
+          "list cannot be full");
+        typedef
+          SMPL_LIST_NAME<
+            T,
+            #define SMPL_arg(z,n,data) T##n
+              BOOST_PP_ENUM(
+                BOOST_PP_SUB(SMPL_LIST_SIZE, 1),
+                SMPL_arg,)
+            #undef SMPL_arg
+          >
+          type;
+      };
+
+      struct is_empty
+      : ::boost::is_same<SMPL_LIST_NAME, SMPL_LIST_NAME<> >
+      {};
+
+      struct empty {
+        typedef
+          SMPL_LIST_NAME<>
+          type;
+      };
+
+    friend class ::smpl::list::head_impl<tag>;
+    friend class ::smpl::list::tail_impl<tag>;
+    friend class ::smpl::list::cons_impl<tag>;
+    friend class ::smpl::list::is_empty_impl<tag>;
+    friend class ::smpl::list::empty<tag>;
+  };
+
+#else
+
+  template<typename...>
+  struct SMPL_LIST_NAME;
+  template<>
+  struct SMPL_LIST_NAME<>
+  #ifdef SMPL_LIST_INHERIT
+  : SMPL_LIST_INHERIT(SMPL_LIST_NAME<>)
+  #endif
+  {
+    public:
+      typedef SMPL_LIST_NAME type;
+      typedef SMPL_TAG_NAME tag;
+    private:
+      template<typename T>
+      struct cons {
+        typedef
+          SMPL_LIST_NAME<T>
+          type;
+      };
+
+      struct is_empty
+      : ::boost::is_same<SMPL_LIST_NAME, SMPL_LIST_NAME<> >
+      {};
+
+      struct empty {
+        typedef
+          SMPL_LIST_NAME<>
+          type;
+      };
+
+    friend class ::smpl::list::cons_impl<tag>;
+    friend class ::smpl::list::is_empty_impl<tag>;
+    friend class ::smpl::list::empty<tag>;
+  };
+  template<typename Head, typename... Tail>
+  struct SMPL_LIST_NAME<Head, Tail...>
+  #ifdef SMPL_LIST_INHERIT
+  : SMPL_LIST_INHERIT(SMPL_LIST_NAME<Head, Tail...>)
+  #endif
+  {
+    public:
+      typedef SMPL_LIST_NAME type;
+      typedef SMPL_TAG_NAME tag;
+    private:
+      
+      struct head {
+        typedef
+          Head
+          type;
+      };
+
+      struct tail {
+        typedef
+          SMPL_LIST_NAME<Tail...>
+          type;
+      };
+
+      template<typename T>
+      struct cons {
+        typedef
+          SMPL_LIST_NAME<T, Head, Tail...>
+          type;
+      };
+
+      struct is_empty
+      : ::boost::is_same<SMPL_LIST_NAME, SMPL_LIST_NAME<> >
+      {};
+
+      struct empty {
+        typedef
+          SMPL_LIST_NAME<>
+          type;
+      };
+
+    friend class ::smpl::list::head_impl<tag>;
+    friend class ::smpl::list::tail_impl<tag>;
+    friend class ::smpl::list::cons_impl<tag>;
+    friend class ::smpl::list::is_empty_impl<tag>;
+    friend class ::smpl::list::empty<tag>;
+  };
+
+#endif
+
+#undef SMPL_TAG_NAME
+#undef SMPL_LIST_NAME
+#undef SMPL_LIST_SIZE
+#undef SMPL_LIST_INHERIT

libdir/smpl/list/impl/members_implement_xmacro.hpp

+// This is an xmacro
+// THIS MUST BE INCLUDED AT GLOBAL SCOPE!
+
+#ifndef SMPL_TAG_NAME
+#error "undefined xmacro parameter: SMPL_TAG_NAME"
+#endif
+
+#include <libdir/smpl/impl/void.hpp>
+#include <libdir/smpl/list/list_interface.hpp>
+
+namespace smpl {
+  namespace list {
+
+    // include guard only necesarry for part of the file
+    #ifndef SMPL_LIST_IMPL_MEMBERS_IMPLEMENT_XMACRO_HPP
+    #define SMPL_LIST_IMPL_MEMBERS_IMPLEMENT_XMACRO_HPP
+
+      namespace impl_empty_member {
+        template<typename List, typename = void>
+        struct empty_member
+        : empty_impl< ::smpl::impl::_ >
+          ::template apply<List>
+        {};
+        template<typename List>
+        struct empty_member<
+          List,
+          typename impl::void_<typename List::empty>::type
+        >
+        : List::empty
+        {};
+      } // namespace impl_head_member
+
+      namespace impl_drop_member {
+        template<int N, typename List, typename = void>
+        struct drop_member
+        : drop_impl< ::smpl::impl::_ >
+          ::template apply<N, List>
+        {};
+        template<int N, typename List>
+        struct drop_member<
+          N,
+          List,
+          typename impl::void_<typename List::template drop<N> >::type
+        >
+        : List::template drop<N>
+        {};
+      } // namespace impl_drop_member
+
+      namespace impl_take_into_member {
+        template<int N, typename List, typename IntoList, typename = void>
+        struct take_into_member
+        : take_into_impl< ::smpl::impl::_ , typename take_into_tag<IntoList>::type>
+          ::template apply<N, List, IntoList>
+        {};
+        template<int N, typename List, typename IntoList>
+        struct take_into_member<
+          N,
+          List,
+          IntoList,
+          typename impl::void_<
+            typename List::template take_into<N, IntoList> >::type
+          >
+        : List::template take_into<N, IntoList>
+        {};
+      } // namespace impl_take_into_member
+
+      namespace impl_take_member {
+        template<int N, typename List, typename = void>
+        struct take_member
+        : take_impl< ::smpl::impl::_ >
+          ::template apply<N, List>
+        {};
+        template<int N, typename List>
+        struct take_member<
+          N,
+          List,
+          typename impl::void_<typename List::template take<N> >::type
+        >
+        : List::template take<N>
+        {};
+      } // namespace impl_take_member
+
+      namespace impl_at_member {
+        template<typename List, int N, typename = void>
+        struct at_member
+        : at_impl< ::smpl::impl::_ >
+          ::template apply<List, N>
+        {};
+        template<typename List, int N>
+        struct at_member<
+          List,
+          N,
+          typename impl::void_<typename List::template at<N> >::type
+        >
+        : List::template at<N>
+        {};
+      } // namespace impl_at_member
+      
+      namespace impl_append_member {
+        template<typename ListA, typename ListB, typename = void>
+        struct append_member
+        : append_impl< ::smpl::impl::_ , typename append_tag<ListB>::type>
+          ::template apply<ListA, ListB>
+        {};
+        template<typename ListA, typename ListB>
+        struct append_member<
+          ListA,
+          ListB,
+          typename impl::void_<typename ListA::template append<ListB> >::type
+        >
+        : ListA::template append<ListB>
+        {};
+      } // namespace impl_append_member
+
+      namespace impl_nest_deeper_member {
+        template<typename List, typename = void>
+        struct nest_deeper_member
+        : nest_deeper_impl< ::smpl::impl::_ >
+          ::template apply<List>
+        {};
+        template<typename List>
+        struct nest_deeper_member<
+          List,
+          typename impl::void_<typename List::nest_deeper>::type
+        >
+        : List::nest_deeper
+        {};
+      } // namespace impl_nest_deeper_member
+
+    #endif // include guard
+
+    // Interface code.
+
+    // Minimum definitions must be members
+
+    template<>
+    struct head_impl< SMPL_TAG_NAME > {
+      template<typename List>
+      struct apply 
+      : List::head
+      {};
+    };
+
+    template<>
+    struct tail_impl< SMPL_TAG_NAME > {
+      template<typename List>
+      struct apply 
+      : List::tail
+      {};
+    };
+
+    template<>
+    struct cons_impl< SMPL_TAG_NAME > {
+      template<typename T, typename List>
+      struct apply 
+      : List::template cons<T>
+      {};
+    };
+
+    template<>
+    struct is_empty_impl< SMPL_TAG_NAME > {
+      template<typename List>
+      struct apply 
+      : List::is_empty
+      {};
+    };
+
+    // Derived metafunctions will use the members as an overload if possible,
+    // otherwise use the normal derivation.
+
+    template<>
+    struct empty_impl< SMPL_TAG_NAME > {
+      template<typename List>
+      struct apply
+      : impl_empty_member::empty_member<List>
+      {};
+    };
+
+    template<>
+    struct drop_impl< SMPL_TAG_NAME > {
+      template<int N, typename List>
+      struct apply
+      : impl_drop_member::drop_member<N, List>
+      {};
+    };
+
+    template<typename ArbitraryTag>
+    struct take_into_impl< SMPL_TAG_NAME , ArbitraryTag> {
+      template<int N, typename List, typename IntoList>
+      struct apply
+      : impl_take_into_member::take_into_member<N, List, IntoList>
+      {};
+    };
+
+    template<>
+    struct take_impl< SMPL_TAG_NAME > {
+      template<int N, typename List>
+      struct apply
+      : impl_take_member::take_member<N, List>
+      {};
+    };
+
+    template<>
+    struct at_impl< SMPL_TAG_NAME > {
+      template<typename List, int N>
+      struct apply
+      : impl_at_member::at_member<List, N>
+      {};
+    };
+
+    template<typename ArbitraryTag>
+    struct append_impl< SMPL_TAG_NAME , ArbitraryTag> {
+      template<typename ListA, typename ListB>
+      struct apply
+      : impl_append_member::append_member<ListA, ListB>
+      {};
+    };
+
+    template<>
+    struct nest_deeper_impl< SMPL_TAG_NAME > {
+      template<typename List>
+      struct apply
+      : impl_nest_deeper_member::nest_deeper_member<List>
+      {};
+    };
+
+  } // namespace list
+} // namespace smpl
+
+#undef SMPL_TAG_NAME
+

libdir/smpl/list/lg_list.hpp

 #include <libdir/smpl/list/list_interface.hpp>
 #include <libdir/smpl/impl/placeholder_type.hpp>
 
-#include <boost/static_assert.hpp>
-#include <boost/preprocessor/cat.hpp>
-#include <boost/preprocessor/arithmetic/sub.hpp>
-#include <boost/preprocessor/repetition/enum.hpp>
-#include <boost/preprocessor/repetition/enum_shifted.hpp>
-#include <boost/preprocessor/repetition/repeat.hpp>
-#include <boost/type_traits/is_same.hpp>
-
 #ifndef SMPL_LIMIT_LG_LIST_SIZE
   #define SMPL_LIMIT_LG_LIST_SIZE 20
 #endif
 
+#include <libdir/smpl/list/impl/lg_list_prerequisites_xmacro.hpp>
+
 namespace smpl {
   namespace list {
 
-    struct lg_tag {};
-
-    #ifdef BOOST_NO_VARIADIC_TEMPLATES
-
-      using impl::_;
-      template<
-        #define SMPL_param(z,n,data) class T##n=_
-          BOOST_PP_ENUM(SMPL_LIMIT_LG_LIST_SIZE, SMPL_param,)
-        #undef SMPL_param
-      >
-      struct lg_list {
-        public:
-          typedef lg_list type;
-          typedef lg_tag tag;
-        private:
-          struct head {
-            typedef
-              T0
-              type;
-          };
-
-          struct tail {
-            typedef
-              lg_list<
-                #define SMPL_arg(z,n,data) BOOST_PP_CAT(T,n)
-                  BOOST_PP_ENUM_SHIFTED(SMPL_LIMIT_LG_LIST_SIZE, SMPL_arg,)
-                #undef SMPL_arg
-                , _
-              >
-              type;
-          };
-
-          template<typename T>
-          struct cons {
-            BOOST_STATIC_ASSERT_MSG(
-              (::boost::is_same<
-                BOOST_PP_CAT(T,
-                  BOOST_PP_SUB(SMPL_LIMIT_LG_LIST_SIZE,1)),
-                _>::value),
-              "list cannot be full");
-            typedef
-              lg_list<
-                T,
-                #define SMPL_arg(z,n,data) T##n
-                  BOOST_PP_ENUM(
-                    BOOST_PP_SUB(SMPL_LIMIT_LG_LIST_SIZE, 1),
-                    SMPL_arg,)
-                #undef SMPL_arg
-              >
-              type;
-          };
-
-        friend class ::smpl::list::head_impl<tag>;
-        friend class ::smpl::list::tail_impl<tag>;
-        friend class ::smpl::list::cons_impl<tag>;
-        friend class ::smpl::list::is_empty_impl<tag>;
-      };
-
-    #else
-
-      template<typename...>
-      struct lg_list;
-      template<>
-      struct lg_list<> {
-        public:
-          typedef lg_list type;
-          typedef lg_tag tag;
-        private:
-          template<typename T>
-          struct cons {
-            typedef
-              lg_list<T>
-              type;
-          };
-
-        friend class ::smpl::list::head_impl<tag>;
-        friend class ::smpl::list::tail_impl<tag>;
-        friend class ::smpl::list::cons_impl<tag>;
-        friend class ::smpl::list::is_empty_impl<tag>;
-      };
-      template<typename Head, typename... Tail>
-      struct lg_list<Head, Tail...> {
-        public:
-          typedef lg_list type;
-          typedef lg_tag tag;
-        private:
-          
-          struct head {
-            typedef
-              Head
-              type;
-          };
-
-          struct tail {
-            typedef
-              lg_list<Tail...>
-              type;
-          };
-
-          template<typename T>
-          struct cons {
-            typedef
-              lg_list<T, Head, Tail...>
-              type;
-          };
-
-        friend class ::smpl::list::head_impl<tag>;
-        friend class ::smpl::list::tail_impl<tag>;
-        friend class ::smpl::list::cons_impl<tag>;
-        friend class ::smpl::list::is_empty_impl<tag>;
-      };
-
-    #endif
-
-    template<>
-    struct head_impl<lg_tag> {
-      template<typename List>
-      struct apply {
-        BOOST_STATIC_ASSERT_MSG(
-          (is_empty<List>::value == false),
-          "list cannot be empty");
-        typedef
-          typename List::head::type
-          type;
-      };
-    };
-
-    template<>
-    struct tail_impl<lg_tag> {
-      template<typename List>
-      struct apply {
-        BOOST_STATIC_ASSERT_MSG(
-          (is_empty<List>::value == false),
-          "list cannot be empty");
-        typedef
-          typename List::tail::type
-          type;
-      };
-    };
-
-    template<>
-    struct cons_impl<lg_tag> {
-      template<typename T, typename List>
-      struct apply {
-        typedef
-          typename List::template cons<T>::type
-          type;
-      };
-    };
-
-    template<>
-    struct is_empty_impl<lg_tag> {
-      template<typename List>
-      struct apply
-      : ::boost::is_same<List, lg_list<> >
-      {};
-    };
-
-    template<>
-    struct empty_impl<lg_tag> {
-      template<typename List>
-      struct apply {
-        typedef
-          lg_list<>
-          type;
-      };
-    };
+    // List container
+    #define SMPL_LIST_NAME lg_list
+    #define SMPL_LIST_SIZE SMPL_LIMIT_LG_LIST_SIZE
+    #define SMPL_TAG_NAME  lg_tag
+    #include <libdir/smpl/list/impl/lg_list_xmacro.hpp>
 
   } // namespace list
 } // namespace smpl
 
+// List interface
+#define SMPL_TAG_NAME lg_tag
+#include <libdir/smpl/list/impl/members_implement_xmacro.hpp>
+
 #include <libdir/smpl/list/impl/list_tests_def.hpp>
 #include SMPL_GENERATE_LIST_TESTS_PREREQUISITES()
 #define SMPL_LIST_EMPTY ::smpl::list::lg_list<>

libdir/smpl/separate_scope.hpp

 #define SMPL_SEPARATE_SCOPE_HPP
 
 #include <libdir/smpl/list_to_separate_scope.hpp>
-
 #include <libdir/smpl/list/list_interface.hpp>
-
 #include <libdir/smpl/vocab/id.hpp>
 
+#ifndef SMPL_LIMIT_SEPARATE_SCOPE_SIZE
+  #define SMPL_LIMIT_SEPARATE_SCOPE_SIZE 20
+#endif
+
+#include <libdir/smpl/list/impl/lg_list_prerequisites_xmacro.hpp>
+
 namespace smpl {
 
-  // smpl::separate_scope composes words together.
+  // List container
+  // smpl::separate_scope composes separate_scopes together.
   // The difference between this and smpl::word is only notable when working
   // with continuations;
-  // smpl::scope uses an artificial continuation which only contains its
+  // smpl::separatescope uses an artificial continuation which only contains its
   // arguments.
-  template<typename... Words>
-  struct separate_scope
-  : list_to_separate_scope< separate_scope<Words...> >
-  {};
-
-  namespace list {
-    
-    template<typename HeadWord, typename... TailWords>
-    struct head<separate_scope<HeadWord, TailWords...> > {
-      typedef
-        HeadWord
-        type;
-    };
-
-    template<typename HeadWord, typename... TailWords>
-    struct tail<separate_scope<HeadWord, TailWords...> > {
-      // list
-      typedef
-        separate_scope<TailWords...>
-        type;
-    };
-
-    template<typename Word, typename... Words>
-    struct cons<Word, separate_scope<Words...> > {
-      // list
-      typedef
-        separate_scope<Word, Words...>
-        type;
-    };
-
-    template<typename... Words>
-    struct is_empty<separate_scope<Words...>> {
-      static bool const value = false;
-    };
-    template<>
-    struct is_empty<separate_scope<> > {
-      static bool const value = true;
-    };
-
-  } // namespace list
+  #define SMPL_LIST_NAME separate_scope
+  #define SMPL_LIST_SIZE SMPL_LIMIT_SEPARATE_SCOPE_SIZE
+  #define SMPL_LIST_INHERIT(ss) list_to_separate_scope<ss>
+  #define SMPL_TAG_NAME  separate_scope_tag
+  #include <libdir/smpl/list/impl/lg_list_xmacro.hpp>
 
 } // namespace smpl
 
+// List interface
+#define SMPL_TAG_NAME ::smpl::separate_scope_tag
+#include <libdir/smpl/list/impl/members_implement_xmacro.hpp>
+
 #endif // include guard
 

libdir/smpl/word.hpp

 #define SMPL_WORD_HPP
 
 #include <libdir/smpl/list_to_word.hpp>
-
 #include <libdir/smpl/list/list_interface.hpp>
-
 #include <libdir/smpl/vocab/id.hpp>
 
+#ifndef SMPL_LIMIT_WORD_SIZE
+  #define SMPL_LIMIT_WORD_SIZE 20
+#endif
+
+#include <libdir/smpl/list/impl/lg_list_prerequisites_xmacro.hpp>
+
 namespace smpl {
 
-  template<typename... Words>
-  struct word
-  : list_to_word< word<Words...> >
-  {};
-
-  namespace list {
-    
-    template<typename HeadWord, typename... TailWords>
-    struct head<word<HeadWord, TailWords...>> {
-      typedef
-        HeadWord
-        type;
-    };
-
-    template<typename HeadWord, typename... TailWords>
-    struct tail<word<HeadWord, TailWords...>> {
-      // list
-      typedef
-        word<TailWords...>
-        type;
-    };
-
-    template<typename Word, typename... Words>
-    struct cons<Word, word<Words...>> {
-      // list
-      typedef
-        word<Word, Words...>
-        type;
-    };
-
-    template<typename... Words>
-    struct is_empty<word<Words...>> {
-      static bool const value = false;
-    };
-    template<>
-    struct is_empty<word<>> {
-      static bool const value = true;
-    };
-
-  } // namespace list
+  // List container
+  #define SMPL_LIST_NAME word
+  #define SMPL_LIST_SIZE SMPL_LIMIT_WORD_SIZE
+  #define SMPL_LIST_INHERIT(word) list_to_word<word>
+  #define SMPL_TAG_NAME  word_tag
+  #include <libdir/smpl/list/impl/lg_list_xmacro.hpp>
 
 } // namespace smpl
 
+// List interface
+#define SMPL_TAG_NAME ::smpl::word_tag
+#include <libdir/smpl/list/impl/members_implement_xmacro.hpp>
+
 #endif // include guard
 
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.