| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380 | ///////////////////////////////////////////////////////////////////////////////// (C) Copyright Ion Gaztanaga  2013-2013//// Distributed under the Boost Software License, Version 1.0.//    (See accompanying file LICENSE_1_0.txt or copy at//          http://www.boost.org/LICENSE_1_0.txt)//// See http://www.boost.org/libs/intrusive for documentation.///////////////////////////////////////////////////////////////////////////////#ifndef BOOST_INTRUSIVE_PACK_OPTIONS_HPP#define BOOST_INTRUSIVE_PACK_OPTIONS_HPP#include <boost/intrusive/detail/config_begin.hpp>#if defined(BOOST_HAS_PRAGMA_ONCE)#  pragma once#endifnamespace boost {namespace intrusive {#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)template<class Prev, class Next>struct do_pack{   //Use "pack" member template to pack options   typedef typename Next::template pack<Prev> type;};template<class Prev>struct do_pack<Prev, void>{   //Avoid packing "void" to shorten template names   typedef Prev type;};template   < class DefaultOptions   , class O1         = void   , class O2         = void   , class O3         = void   , class O4         = void   , class O5         = void   , class O6         = void   , class O7         = void   , class O8         = void   , class O9         = void   , class O10        = void   , class O11        = void   >struct pack_options{   // join options   typedef      typename do_pack      <  typename do_pack         <  typename do_pack            <  typename do_pack               <  typename do_pack                  <  typename do_pack                     <  typename do_pack                        <  typename do_pack                           <  typename do_pack                              <  typename do_pack                                 <  typename do_pack                                    < DefaultOptions                                    , O1                                    >::type                                 , O2                                 >::type                              , O3                              >::type                           , O4                           >::type                        , O5                        >::type                     , O6                     >::type                  , O7                  >::type               , O8               >::type            , O9            >::type         , O10         >::type      , O11      >::type   type;};#else//index_tupletemplate<int... Indexes>struct index_tuple{};//build_number_seqtemplate<std::size_t Num, typename Tuple = index_tuple<> >struct build_number_seq;template<std::size_t Num, int... Indexes>struct build_number_seq<Num, index_tuple<Indexes...> >   : build_number_seq<Num - 1, index_tuple<Indexes..., sizeof...(Indexes)> >{};template<int... Indexes>struct build_number_seq<0, index_tuple<Indexes...> >{  typedef index_tuple<Indexes...> type;  };template<class ...Types>struct typelist{};//invert_typelisttemplate<class T>struct invert_typelist;template<int I, typename Tuple>struct typelist_element;template<int I, typename Head, typename... Tail>struct typelist_element<I, typelist<Head, Tail...> >{   typedef typename typelist_element<I-1, typelist<Tail...> >::type type;};template<typename Head, typename... Tail>struct typelist_element<0, typelist<Head, Tail...> >{   typedef Head type;};template<int ...Ints, class ...Types>typelist<typename typelist_element<(sizeof...(Types) - 1) - Ints, typelist<Types...> >::type...>   inverted_typelist(index_tuple<Ints...>, typelist<Types...>){   return typelist<typename typelist_element<(sizeof...(Types) - 1) - Ints, typelist<Types...> >::type...>();}//sizeof_typelisttemplate<class Typelist>struct sizeof_typelist;template<class ...Types>struct sizeof_typelist< typelist<Types...> >{   static const std::size_t value = sizeof...(Types);};//invert_typelist_impltemplate<class Typelist, class Indexes>struct invert_typelist_impl;template<class Typelist, int ...Ints>struct invert_typelist_impl< Typelist, index_tuple<Ints...> >{   static const std::size_t last_idx = sizeof_typelist<Typelist>::value - 1;   typedef typelist      <typename typelist_element<last_idx - Ints, Typelist>::type...> type;};template<class Typelist, int Int>struct invert_typelist_impl< Typelist, index_tuple<Int> >{   typedef Typelist type;};template<class Typelist>struct invert_typelist_impl< Typelist, index_tuple<> >{   typedef Typelist type;};//invert_typelisttemplate<class Typelist>struct invert_typelist;template<class ...Types>struct invert_typelist< typelist<Types...> >{   typedef typelist<Types...> typelist_t;   typedef typename build_number_seq<sizeof...(Types)>::type indexes_t;   typedef typename invert_typelist_impl<typelist_t, indexes_t>::type type;};//Do packtemplate<class Typelist>struct do_pack;template<>struct do_pack<typelist<> >;template<class Prev>struct do_pack<typelist<Prev> >{   typedef Prev type;};template<class Prev, class Last>struct do_pack<typelist<Prev, Last> >{   typedef typename Prev::template pack<Last> type;};template<class ...Others>struct do_pack<typelist<void, Others...> >{   typedef typename do_pack<typelist<Others...> >::type type;};template<class Prev, class ...Others>struct do_pack<typelist<Prev, Others...> >{   typedef typename Prev::template pack      <typename do_pack<typelist<Others...> >::type> type;};template<class DefaultOptions, class ...Options>struct pack_options{   typedef typelist<DefaultOptions, Options...> typelist_t;   typedef typename invert_typelist<typelist_t>::type inverted_typelist;   typedef typename do_pack<inverted_typelist>::type type;};#endif   //!defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)#define BOOST_INTRUSIVE_OPTION_TYPE(OPTION_NAME, TYPE, TYPEDEF_EXPR, TYPEDEF_NAME) \template< class TYPE> \struct OPTION_NAME \{ \   template<class Base> \   struct pack : Base \   { \      typedef TYPEDEF_EXPR TYPEDEF_NAME; \   }; \}; \//#define BOOST_INTRUSIVE_OPTION_CONSTANT(OPTION_NAME, TYPE, VALUE, CONSTANT_NAME) \template< TYPE VALUE> \struct OPTION_NAME \{ \   template<class Base> \   struct pack : Base \   { \      static const TYPE CONSTANT_NAME = VALUE; \   }; \}; \//#else    //#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED//! This class is a utility that takes://!   - a default options class defining initial static constant//!   and typedefs//!   - several options defined with BOOST_INTRUSIVE_OPTION_CONSTANT and//! BOOST_INTRUSIVE_OPTION_TYPE//!//! and packs them together in a new type that defines all options as//! member typedefs or static constant values. Given options of form://!//! \code//!   BOOST_INTRUSIVE_OPTION_TYPE(my_pointer, VoidPointer, VoidPointer, my_pointer_type)//!   BOOST_INTRUSIVE_OPTION_CONSTANT(incremental, bool, Enabled, is_incremental)//! \endcode//!//! the following expression//!//! \code//!//! struct default_options//! {//!   typedef long      int_type;//!   static const int  int_constant = -1;//! };//!//! pack_options< default_options, my_pointer<void*>, incremental<true> >::type//! \endcode//!//! will create a type that will contain the following typedefs/constants//!//! \code//!   struct unspecified_type//!   {//!      //Default options//!      typedef long      int_type;//!      static const int  int_constant  = -1;//!//!      //Packed options (will ovewrite any default option)//!      typedef void*     my_pointer_type;//!      static const bool is_incremental = true;//!   };//! \endcode//!//! If an option is specified in the default options argument and later//! redefined as an option, the last definition will prevail.template<class DefaultOptions, class ...Options>struct pack_options{   typedef unspecified_type type;};//! Defines an option class of name OPTION_NAME that can be used to specify a type//! of type TYPE...//!//! \code//! struct OPTION_NAME<class TYPE>//! {  unspecified_content  };//! \endcode//!//! ...that after being combined with//! <code>boost::intrusive::pack_options</code>,//! will typedef TYPE as a typedef of name TYPEDEF_NAME. Example://!//! \code//!   //[includes and namespaces omitted for brevity]//!//!   //This macro will create the following class://!   //    template<class VoidPointer>//!   //    struct my_pointer//!   //    { unspecified_content };//!   BOOST_INTRUSIVE_OPTION_TYPE(my_pointer, VoidPointer, boost::remove_pointer<VoidPointer>::type, my_pointer_type)//!//!   struct empty_default{};//!//!   typedef pack_options< empty_default, typename my_pointer<void*> >::type::my_pointer_type type;//!//!   BOOST_STATIC_ASSERT(( boost::is_same<type, void>::value ));//!//! \endcode#define BOOST_INTRUSIVE_OPTION_TYPE(OPTION_NAME, TYPE, TYPEDEF_EXPR, TYPEDEF_NAME)//! Defines an option class of name OPTION_NAME that can be used to specify a constant//! of type TYPE with value VALUE...//!//! \code//! struct OPTION_NAME<TYPE VALUE>//! {  unspecified_content  };//! \endcode//!//! ...that after being combined with//! <code>boost::intrusive::pack_options</code>,//! will contain a CONSTANT_NAME static constant of value VALUE. Example://!//! \code//!   //[includes and namespaces omitted for brevity]//!//!   //This macro will create the following class://!   //    template<bool Enabled>//!   //    struct incremental//!   //    { unspecified_content };//!   BOOST_INTRUSIVE_OPTION_CONSTANT(incremental, bool, Enabled, is_incremental)//!//!   struct empty_default{};//!//!   const bool is_incremental = pack_options< empty_default, incremental<true> >::type::is_incremental;//!//!   BOOST_STATIC_ASSERT(( is_incremental == true ));//!//! \endcode#define BOOST_INTRUSIVE_OPTION_CONSTANT(OPTION_NAME, TYPE, VALUE, CONSTANT_NAME)#endif   //#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED}  //namespace intrusive {}  //namespace boost {#include <boost/intrusive/detail/config_end.hpp>#endif   //#ifndef BOOST_INTRUSIVE_PACK_OPTIONS_HPP
 |