Back to home page

EIC code displayed by LXR

 
 

    


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

0001 /* Copyright 2003-2013 Joaquin M Lopez Munoz.
0002  * Distributed under the Boost Software License, Version 1.0.
0003  * (See accompanying file LICENSE_1_0.txt or copy at
0004  * http://www.boost.org/LICENSE_1_0.txt)
0005  *
0006  * See http://www.boost.org/libs/multi_index for library home page.
0007  */
0008 
0009 #ifndef BOOST_MULTI_INDEX_DETAIL_VARTEMPL_SUPPORT_HPP
0010 #define BOOST_MULTI_INDEX_DETAIL_VARTEMPL_SUPPORT_HPP
0011 
0012 #if defined(_MSC_VER)
0013 #pragma once
0014 #endif
0015 
0016 /* Utilities for emulation of variadic template functions. Variadic packs are
0017  * replaced by lists of BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS parameters:
0018  *
0019  *   - typename... Args            --> BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK
0020  *   - Args&&... args              --> BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK
0021  *   - std::forward<Args>(args)... --> BOOST_MULTI_INDEX_FORWARD_PARAM_PACK
0022  *
0023  * Forwarding emulated with Boost.Move. A template functions foo_imp
0024  * defined in such way accepts *exactly* BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS
0025  * arguments: variable number of arguments is emulated by providing a set of
0026  * overloads foo forwarding to foo_impl with
0027  * 
0028  *   BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL
0029  *   BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG (initial extra arg)
0030  *
0031  * which fill the extra args with boost::multi_index::detail::noarg's.
0032  * boost::multi_index::detail::vartempl_placement_new works the opposite
0033  * way: it acceps a full a pointer x to Value and a
0034  * BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK and forwards to
0035  * new(x) Value(args) where args is the argument pack after discarding
0036  * noarg's.
0037  *
0038  * Emulation decays to the real thing when the compiler supports variadic
0039  * templates and move semantics natively.
0040  */
0041 
0042 #include <boost/config.hpp>
0043 
0044 #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)||\
0045     defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0046 
0047 #include <boost/move/core.hpp>
0048 #include <boost/move/utility.hpp>
0049 #include <boost/preprocessor/arithmetic/add.hpp>
0050 #include <boost/preprocessor/arithmetic/sub.hpp>
0051 #include <boost/preprocessor/cat.hpp>
0052 #include <boost/preprocessor/control/if.hpp>
0053 #include <boost/preprocessor/facilities/empty.hpp>
0054 #include <boost/preprocessor/facilities/intercept.hpp>
0055 #include <boost/preprocessor/logical/and.hpp>
0056 #include <boost/preprocessor/punctuation/comma.hpp>
0057 #include <boost/preprocessor/punctuation/comma_if.hpp>
0058 #include <boost/preprocessor/repetition/enum.hpp>
0059 #include <boost/preprocessor/repetition/enum_params.hpp>
0060 #include <boost/preprocessor/repetition/repeat_from_to.hpp>
0061 #include <boost/preprocessor/seq/elem.hpp>
0062 
0063 #if !defined(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS)
0064 #define BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS 5
0065 #endif
0066 
0067 #define BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK                        \
0068 BOOST_PP_ENUM_PARAMS(                                                \
0069   BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,typename T)
0070 
0071 #define BOOST_MULTI_INDEX_VARTEMPL_ARG(z,n,_)                        \
0072 BOOST_FWD_REF(BOOST_PP_CAT(T,n)) BOOST_PP_CAT(t,n)
0073 
0074 #define BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK                        \
0075 BOOST_PP_ENUM(                                                       \
0076   BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,                             \
0077   BOOST_MULTI_INDEX_VARTEMPL_ARG,~)
0078 
0079 #define BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG(z,n,_)                \
0080 boost::forward<BOOST_PP_CAT(T,n)>(BOOST_PP_CAT(t,n))
0081 
0082 #define BOOST_MULTI_INDEX_FORWARD_PARAM_PACK                         \
0083 BOOST_PP_ENUM(                                                       \
0084   BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,                             \
0085   BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG,~)
0086 
0087 namespace boost{namespace multi_index{namespace detail{
0088 struct noarg{};
0089 }}}
0090 
0091 /* call vartempl function without args */
0092 
0093 #define BOOST_MULTI_INDEX_NULL_PARAM_PACK                            \
0094 BOOST_PP_ENUM_PARAMS(                                                \
0095   BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,                             \
0096   boost::multi_index::detail::noarg() BOOST_PP_INTERCEPT)
0097 
0098 #define BOOST_MULTI_INDEX_TEMPLATE_N(n)                              \
0099 template<BOOST_PP_ENUM_PARAMS(n,typename T)>
0100 
0101 #define BOOST_MULTI_INDEX_TEMPLATE_0(n)
0102 
0103 #define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_AUX(z,n,data)        \
0104 BOOST_PP_IF(n,                                                       \
0105   BOOST_MULTI_INDEX_TEMPLATE_N,                                      \
0106   BOOST_MULTI_INDEX_TEMPLATE_0)(n)                                   \
0107 BOOST_PP_SEQ_ELEM(0,data) /* ret */                                  \
0108 BOOST_PP_SEQ_ELEM(1,data) /* name_from */ (                          \
0109   BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_ARG,~))                 \
0110 {                                                                    \
0111   return BOOST_PP_SEQ_ELEM(2,data) /* name_to */ (                   \
0112     BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG,~)        \
0113     BOOST_PP_COMMA_IF(                                               \
0114       BOOST_PP_AND(                                                  \
0115         n,BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n)))    \
0116     BOOST_PP_ENUM_PARAMS(                                            \
0117       BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n),         \
0118       boost::multi_index::detail::noarg() BOOST_PP_INTERCEPT)        \
0119   );                                                                 \
0120 }
0121 
0122 #define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL(                     \
0123   ret,name_from,name_to)                                             \
0124 BOOST_PP_REPEAT_FROM_TO(                                             \
0125   0,BOOST_PP_ADD(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,1),           \
0126   BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_AUX,                       \
0127   (ret)(name_from)(name_to))
0128 
0129 #define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG_AUX(       \
0130   z,n,data)                                                          \
0131 BOOST_PP_IF(n,                                                       \
0132   BOOST_MULTI_INDEX_TEMPLATE_N,                                      \
0133   BOOST_MULTI_INDEX_TEMPLATE_0)(n)                                   \
0134 BOOST_PP_SEQ_ELEM(0,data) /* ret */                                  \
0135 BOOST_PP_SEQ_ELEM(1,data) /* name_from */ (                          \
0136   BOOST_PP_SEQ_ELEM(3,data) BOOST_PP_SEQ_ELEM(4,data) /* extra arg */\
0137   BOOST_PP_COMMA_IF(n)                                               \
0138   BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_ARG,~))                 \
0139 {                                                                    \
0140   return BOOST_PP_SEQ_ELEM(2,data) /* name_to */ (                   \
0141     BOOST_PP_SEQ_ELEM(4,data) /* extra_arg_name */                   \
0142     BOOST_PP_COMMA_IF(n)                                             \
0143     BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG,~)        \
0144     BOOST_PP_COMMA_IF(                                               \
0145       BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n))         \
0146     BOOST_PP_ENUM_PARAMS(                                            \
0147       BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n),         \
0148       boost::multi_index::detail::noarg() BOOST_PP_INTERCEPT)        \
0149   );                                                                 \
0150 }
0151 
0152 #define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG(           \
0153   ret,name_from,name_to,extra_arg_type,extra_arg_name)               \
0154 BOOST_PP_REPEAT_FROM_TO(                                             \
0155   0,BOOST_PP_ADD(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,1),           \
0156   BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG_AUX,             \
0157   (ret)(name_from)(name_to)(extra_arg_type)(extra_arg_name))
0158 
0159 namespace boost{
0160   
0161 namespace multi_index{
0162   
0163 namespace detail{
0164 
0165 #define BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW_AUX(z,n,name)    \
0166 template<                                                            \
0167   typename Value                                                     \
0168   BOOST_PP_COMMA_IF(n)                                               \
0169   BOOST_PP_ENUM_PARAMS(n,typename T)                                 \
0170 >                                                                    \
0171 Value* name(                                                         \
0172   Value* x                                                           \
0173   BOOST_PP_COMMA_IF(n)                                               \
0174   BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_ARG,~)                  \
0175   BOOST_PP_COMMA_IF(                                                 \
0176     BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n))           \
0177   BOOST_PP_ENUM_PARAMS(                                              \
0178     BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n),           \
0179     BOOST_FWD_REF(noarg) BOOST_PP_INTERCEPT))                        \
0180 {                                                                    \
0181   return new(x) Value(                                               \
0182     BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG,~));      \
0183 }
0184 
0185 #define BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW(name)            \
0186 BOOST_PP_REPEAT_FROM_TO(                                             \
0187   0,BOOST_PP_ADD(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,1),           \
0188   BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW_AUX,                   \
0189   name)
0190 
0191 BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW(vartempl_placement_new)
0192 
0193 #undef BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW_AUX
0194 #undef BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW
0195 
0196 } /* namespace multi_index::detail */
0197 
0198 } /* namespace multi_index */
0199 
0200 } /* namespace boost */
0201 
0202 #else
0203 
0204 /* native variadic templates support */
0205 
0206 #include <utility>
0207 
0208 #define BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK typename... Args
0209 #define BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK Args&&... args
0210 #define BOOST_MULTI_INDEX_FORWARD_PARAM_PACK  std::forward<Args>(args)...
0211 #define BOOST_MULTI_INDEX_NULL_PARAM_PACK
0212 
0213 #define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL(                     \
0214   ret,name_from,name_to)                                             \
0215 template<typename... Args> ret name_from(Args&&... args)             \
0216 {                                                                    \
0217   return name_to(std::forward<Args>(args)...);                       \
0218 }
0219 
0220 #define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG(           \
0221   ret,name_from,name_to,extra_arg_type,extra_arg_name)               \
0222 template<typename... Args> ret name_from(                            \
0223   extra_arg_type extra_arg_name,Args&&... args)                      \
0224 {                                                                    \
0225   return name_to(extra_arg_name,std::forward<Args>(args)...);        \
0226 }
0227 
0228 namespace boost{
0229   
0230 namespace multi_index{
0231   
0232 namespace detail{
0233 
0234 template<typename Value,typename... Args>
0235 Value* vartempl_placement_new(Value*x,Args&&... args)
0236 {
0237   return new(x) Value(std::forward<Args>(args)...);
0238 }
0239 
0240 } /* namespace multi_index::detail */
0241 
0242 } /* namespace multi_index */
0243 
0244 } /* namespace boost */
0245 
0246 #endif
0247 #endif