Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:38:42

0001 /////////////////////////////////////////////////////////////////////////////
0002 //
0003 // (C) Copyright Ion Gaztanaga  2013-2013
0004 //
0005 // Distributed under the Boost Software License, Version 1.0.
0006 //    (See accompanying file LICENSE_1_0.txt or copy at
0007 //          http://www.boost.org/LICENSE_1_0.txt)
0008 //
0009 // See http://www.boost.org/libs/intrusive for documentation.
0010 //
0011 /////////////////////////////////////////////////////////////////////////////
0012 
0013 #ifndef BOOST_INTRUSIVE_PACK_OPTIONS_HPP
0014 #define BOOST_INTRUSIVE_PACK_OPTIONS_HPP
0015 
0016 #include <boost/intrusive/detail/config_begin.hpp>
0017 
0018 #if defined(BOOST_HAS_PRAGMA_ONCE)
0019 #  pragma once
0020 #endif
0021 
0022 #include <cstddef>
0023 
0024 namespace boost {
0025 namespace intrusive {
0026 
0027 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0028 
0029 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
0030 
0031 template<class Prev, class Next>
0032 struct do_pack
0033 {
0034    //Use "pack" member template to pack options
0035    typedef typename Next::template pack<Prev> type;
0036 };
0037 
0038 template<class Prev>
0039 struct do_pack<Prev, void>
0040 {
0041    //Avoid packing "void" to shorten template names
0042    typedef Prev type;
0043 };
0044 
0045 template
0046    < class DefaultOptions
0047    , class O1         = void
0048    , class O2         = void
0049    , class O3         = void
0050    , class O4         = void
0051    , class O5         = void
0052    , class O6         = void
0053    , class O7         = void
0054    , class O8         = void
0055    , class O9         = void
0056    , class O10        = void
0057    , class O11        = void
0058    >
0059 struct pack_options
0060 {
0061    // join options
0062    typedef
0063       typename do_pack
0064       <  typename do_pack
0065          <  typename do_pack
0066             <  typename do_pack
0067                <  typename do_pack
0068                   <  typename do_pack
0069                      <  typename do_pack
0070                         <  typename do_pack
0071                            <  typename do_pack
0072                               <  typename do_pack
0073                                  <  typename do_pack
0074                                     < DefaultOptions
0075                                     , O1
0076                                     >::type
0077                                  , O2
0078                                  >::type
0079                               , O3
0080                               >::type
0081                            , O4
0082                            >::type
0083                         , O5
0084                         >::type
0085                      , O6
0086                      >::type
0087                   , O7
0088                   >::type
0089                , O8
0090                >::type
0091             , O9
0092             >::type
0093          , O10
0094          >::type
0095       , O11
0096       >::type
0097    type;
0098 };
0099 #else
0100 
0101 //index_tuple
0102 template<std::size_t... Indexes>
0103 struct index_tuple{};
0104 
0105 //build_number_seq
0106 template<std::size_t Num, typename Tuple = index_tuple<> >
0107 struct build_number_seq;
0108 
0109 template<std::size_t Num, std::size_t... Indexes>
0110 struct build_number_seq<Num, index_tuple<Indexes...> >
0111    : build_number_seq<Num - 1, index_tuple<Indexes..., sizeof...(Indexes)> >
0112 {};
0113 
0114 template<std::size_t... Indexes>
0115 struct build_number_seq<0, index_tuple<Indexes...> >
0116 {  typedef index_tuple<Indexes...> type;  };
0117 
0118 template<class ...Types>
0119 struct typelist
0120 {};
0121 
0122 //invert_typelist
0123 template<class T>
0124 struct invert_typelist;
0125 
0126 template<std::size_t I, typename Tuple>
0127 struct typelist_element;
0128 
0129 template<std::size_t I, typename Head, typename... Tail>
0130 struct typelist_element<I, typelist<Head, Tail...> >
0131 {
0132    typedef typename typelist_element<I-1, typelist<Tail...> >::type type;
0133 };
0134 
0135 template<typename Head, typename... Tail>
0136 struct typelist_element<0, typelist<Head, Tail...> >
0137 {
0138    typedef Head type;
0139 };
0140 
0141 template<std::size_t ...Ints, class ...Types>
0142 typelist<typename typelist_element<(sizeof...(Types) - 1) - Ints, typelist<Types...> >::type...>
0143    inverted_typelist(index_tuple<Ints...>, typelist<Types...>)
0144 {
0145    return typelist<typename typelist_element<(sizeof...(Types) - 1) - Ints, typelist<Types...> >::type...>();
0146 }
0147 
0148 //sizeof_typelist
0149 template<class Typelist>
0150 struct sizeof_typelist;
0151 
0152 template<class ...Types>
0153 struct sizeof_typelist< typelist<Types...> >
0154 {
0155    static const std::size_t value = sizeof...(Types);
0156 };
0157 
0158 //invert_typelist_impl
0159 template<class Typelist, class Indexes>
0160 struct invert_typelist_impl;
0161 
0162 
0163 template<class Typelist, std::size_t ...Ints>
0164 struct invert_typelist_impl< Typelist, index_tuple<Ints...> >
0165 {
0166    static const std::size_t last_idx = sizeof_typelist<Typelist>::value - 1;
0167    typedef typelist
0168       <typename typelist_element<last_idx - Ints, Typelist>::type...> type;
0169 };
0170 
0171 template<class Typelist, std::size_t Int>
0172 struct invert_typelist_impl< Typelist, index_tuple<Int> >
0173 {
0174    typedef Typelist type;
0175 };
0176 
0177 template<class Typelist>
0178 struct invert_typelist_impl< Typelist, index_tuple<> >
0179 {
0180    typedef Typelist type;
0181 };
0182 
0183 //invert_typelist
0184 template<class Typelist>
0185 struct invert_typelist;
0186 
0187 template<class ...Types>
0188 struct invert_typelist< typelist<Types...> >
0189 {
0190    typedef typelist<Types...> typelist_t;
0191    typedef typename build_number_seq<sizeof...(Types)>::type indexes_t;
0192    typedef typename invert_typelist_impl<typelist_t, indexes_t>::type type;
0193 };
0194 
0195 //Do pack
0196 template<class Typelist>
0197 struct do_pack;
0198 
0199 template<>
0200 struct do_pack<typelist<> >;
0201 
0202 template<class Prev>
0203 struct do_pack<typelist<Prev> >
0204 {
0205    typedef Prev type;
0206 };
0207 
0208 template<class Prev, class Last>
0209 struct do_pack<typelist<Prev, Last> >
0210 {
0211    typedef typename Prev::template pack<Last> type;
0212 };
0213 
0214 template<class ...Others>
0215 struct do_pack<typelist<void, Others...> >
0216 {
0217    typedef typename do_pack<typelist<Others...> >::type type;
0218 };
0219 
0220 template<class Prev, class ...Others>
0221 struct do_pack<typelist<Prev, Others...> >
0222 {
0223    typedef typename Prev::template pack
0224       <typename do_pack<typelist<Others...> >::type> type;
0225 };
0226 
0227 
0228 template<class DefaultOptions, class ...Options>
0229 struct pack_options
0230 {
0231    typedef typelist<DefaultOptions, Options...> typelist_t;
0232    typedef typename invert_typelist<typelist_t>::type inverted_typelist;
0233    typedef typename do_pack<inverted_typelist>::type type;
0234 };
0235 
0236 #endif   //!defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
0237 
0238 #define BOOST_INTRUSIVE_OPTION_TYPE(OPTION_NAME, TYPE, TYPEDEF_EXPR, TYPEDEF_NAME) \
0239 template< class TYPE> \
0240 struct OPTION_NAME \
0241 { \
0242    template<class Base> \
0243    struct pack : Base \
0244    { \
0245       typedef TYPEDEF_EXPR TYPEDEF_NAME; \
0246    }; \
0247 }; \
0248 //
0249 
0250 #define BOOST_INTRUSIVE_OPTION_CONSTANT(OPTION_NAME, TYPE, VALUE, CONSTANT_NAME) \
0251 template< TYPE VALUE> \
0252 struct OPTION_NAME \
0253 { \
0254    static const TYPE value = VALUE; \
0255  \
0256    template<class Base> \
0257    struct pack : Base \
0258    { \
0259       static const TYPE CONSTANT_NAME = VALUE; \
0260    }; \
0261 }; \
0262 //
0263 
0264 #else    //#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0265 
0266 //! This class is a utility that takes:
0267 //!   - a default options class defining initial static constant
0268 //!   and typedefs
0269 //!   - several options defined with BOOST_INTRUSIVE_OPTION_CONSTANT and
0270 //! BOOST_INTRUSIVE_OPTION_TYPE
0271 //!
0272 //! and packs them together in a new type that defines all options as
0273 //! member typedefs or static constant values. Given options of form:
0274 //!
0275 //! \code
0276 //!   BOOST_INTRUSIVE_OPTION_TYPE(my_pointer, VoidPointer, VoidPointer, my_pointer_type)
0277 //!   BOOST_INTRUSIVE_OPTION_CONSTANT(incremental, bool, Enabled, is_incremental)
0278 //! \endcode
0279 //!
0280 //! the following expression
0281 //!
0282 //! \code
0283 //!
0284 //! struct default_options
0285 //! {
0286 //!   typedef long      int_type;
0287 //!   static const int  int_constant = -1;
0288 //! };
0289 //!
0290 //! pack_options< default_options, my_pointer<void*>, incremental<true> >::type
0291 //! \endcode
0292 //!
0293 //! will create a type that will contain the following typedefs/constants
0294 //!
0295 //! \code
0296 //!   struct unspecified_type
0297 //!   {
0298 //!      //Default options
0299 //!      typedef long      int_type;
0300 //!      static const int  int_constant  = -1;
0301 //!
0302 //!      //Packed options (will ovewrite any default option)
0303 //!      typedef void*     my_pointer_type;
0304 //!      static const bool is_incremental = true;
0305 //!   };
0306 //! \endcode
0307 //!
0308 //! If an option is specified in the default options argument and later
0309 //! redefined as an option, the last definition will prevail.
0310 template<class DefaultOptions, class ...Options>
0311 struct pack_options
0312 {
0313    typedef unspecified_type type;
0314 };
0315 
0316 //! Defines an option class of name OPTION_NAME that can be used to specify a type
0317 //! of type TYPE...
0318 //!
0319 //! \code
0320 //! struct OPTION_NAME<class TYPE>
0321 //! {  unspecified_content  };
0322 //! \endcode
0323 //!
0324 //! ...that after being combined with
0325 //! <code>boost::intrusive::pack_options</code>,
0326 //! will typedef TYPE as a typedef of name TYPEDEF_NAME. Example:
0327 //!
0328 //! \code
0329 //!   //[includes and namespaces omitted for brevity]
0330 //!
0331 //!   //This macro will create the following class:
0332 //!   //    template<class VoidPointer>
0333 //!   //    struct my_pointer
0334 //!   //    { unspecified_content };
0335 //!   BOOST_INTRUSIVE_OPTION_TYPE(my_pointer, VoidPointer, boost::remove_pointer<VoidPointer>::type, my_pointer_type)
0336 //!
0337 //!   struct empty_default{};
0338 //!
0339 //!   typedef pack_options< empty_default, typename my_pointer<void*> >::type::my_pointer_type type;
0340 //!
0341 //!   BOOST_STATIC_ASSERT(( boost::is_same<type, void>::value ));
0342 //!
0343 //! \endcode
0344 #define BOOST_INTRUSIVE_OPTION_TYPE(OPTION_NAME, TYPE, TYPEDEF_EXPR, TYPEDEF_NAME)
0345 
0346 //! Defines an option class of name OPTION_NAME that can be used to specify a constant
0347 //! of type TYPE with value VALUE...
0348 //!
0349 //! \code
0350 //! struct OPTION_NAME<TYPE VALUE>
0351 //! {  unspecified_content  };
0352 //! \endcode
0353 //!
0354 //! ...that after being combined with
0355 //! <code>boost::intrusive::pack_options</code>,
0356 //! will contain a CONSTANT_NAME static constant of value VALUE. Example:
0357 //!
0358 //! \code
0359 //!   //[includes and namespaces omitted for brevity]
0360 //!
0361 //!   //This macro will create the following class:
0362 //!   //    template<bool Enabled>
0363 //!   //    struct incremental
0364 //!   //    { unspecified_content };
0365 //!   BOOST_INTRUSIVE_OPTION_CONSTANT(incremental, bool, Enabled, is_incremental)
0366 //!
0367 //!   struct empty_default{};
0368 //!
0369 //!   const bool is_incremental = pack_options< empty_default, incremental<true> >::type::is_incremental;
0370 //!
0371 //!   BOOST_STATIC_ASSERT(( is_incremental == true ));
0372 //!
0373 //! \endcode
0374 #define BOOST_INTRUSIVE_OPTION_CONSTANT(OPTION_NAME, TYPE, VALUE, CONSTANT_NAME)
0375 
0376 #endif   //#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0377 
0378 
0379 }  //namespace intrusive {
0380 }  //namespace boost {
0381 
0382 #include <boost/intrusive/detail/config_end.hpp>
0383 
0384 #endif   //#ifndef BOOST_INTRUSIVE_PACK_OPTIONS_HPP