annotate DEPENDENCIES/generic/include/boost/multi_index/detail/vartempl_support.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 /* Copyright 2003-2013 Joaquin M Lopez Munoz.
Chris@16 2 * Distributed under the Boost Software License, Version 1.0.
Chris@16 3 * (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 4 * http://www.boost.org/LICENSE_1_0.txt)
Chris@16 5 *
Chris@16 6 * See http://www.boost.org/libs/multi_index for library home page.
Chris@16 7 */
Chris@16 8
Chris@16 9 #ifndef BOOST_MULTI_INDEX_DETAIL_VARTEMPL_SUPPORT_HPP
Chris@16 10 #define BOOST_MULTI_INDEX_DETAIL_VARTEMPL_SUPPORT_HPP
Chris@16 11
Chris@101 12 #if defined(_MSC_VER)
Chris@16 13 #pragma once
Chris@16 14 #endif
Chris@16 15
Chris@16 16 /* Utilities for emulation of variadic template functions. Variadic packs are
Chris@16 17 * replaced by lists of BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS parameters:
Chris@16 18 *
Chris@16 19 * - typename... Args --> BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK
Chris@16 20 * - Args&&... args --> BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK
Chris@16 21 * - std::forward<Args>(args)... --> BOOST_MULTI_INDEX_FORWARD_PARAM_PACK
Chris@16 22 *
Chris@16 23 * Forwarding emulated with Boost.Move. A template functions foo_imp
Chris@16 24 * defined in such way accepts *exactly* BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS
Chris@16 25 * arguments: variable number of arguments is emulated by providing a set of
Chris@16 26 * overloads foo forwarding to foo_impl with
Chris@16 27 *
Chris@16 28 * BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL
Chris@16 29 * BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG (initial extra arg)
Chris@16 30 *
Chris@16 31 * which fill the extra args with boost::multi_index::detail::noarg's.
Chris@16 32 * boost::multi_index::detail::vartempl_placement_new works the opposite
Chris@16 33 * way: it acceps a full a pointer x to Value and a
Chris@16 34 * BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK and forwards to
Chris@16 35 * new(x) Value(args) where args is the argument pack after discarding
Chris@16 36 * noarg's.
Chris@16 37 *
Chris@16 38 * Emulation decays to the real thing when the compiler supports variadic
Chris@16 39 * templates and move semantics natively.
Chris@16 40 */
Chris@16 41
Chris@16 42 #include <boost/config.hpp>
Chris@16 43
Chris@16 44 #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)||\
Chris@16 45 defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
Chris@16 46
Chris@16 47 #include <boost/move/core.hpp>
Chris@16 48 #include <boost/move/utility.hpp>
Chris@16 49 #include <boost/preprocessor/arithmetic/add.hpp>
Chris@16 50 #include <boost/preprocessor/arithmetic/sub.hpp>
Chris@16 51 #include <boost/preprocessor/cat.hpp>
Chris@16 52 #include <boost/preprocessor/control/if.hpp>
Chris@16 53 #include <boost/preprocessor/facilities/empty.hpp>
Chris@16 54 #include <boost/preprocessor/facilities/intercept.hpp>
Chris@16 55 #include <boost/preprocessor/logical/and.hpp>
Chris@16 56 #include <boost/preprocessor/punctuation/comma.hpp>
Chris@16 57 #include <boost/preprocessor/punctuation/comma_if.hpp>
Chris@16 58 #include <boost/preprocessor/repetition/enum.hpp>
Chris@16 59 #include <boost/preprocessor/repetition/enum_params.hpp>
Chris@16 60 #include <boost/preprocessor/repetition/repeat_from_to.hpp>
Chris@16 61 #include <boost/preprocessor/seq/elem.hpp>
Chris@16 62
Chris@16 63 #if !defined(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS)
Chris@16 64 #define BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS 5
Chris@16 65 #endif
Chris@16 66
Chris@16 67 #define BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK \
Chris@16 68 BOOST_PP_ENUM_PARAMS( \
Chris@16 69 BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,typename T)
Chris@16 70
Chris@16 71 #define BOOST_MULTI_INDEX_VARTEMPL_ARG(z,n,_) \
Chris@16 72 BOOST_FWD_REF(BOOST_PP_CAT(T,n)) BOOST_PP_CAT(t,n)
Chris@16 73
Chris@16 74 #define BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK \
Chris@16 75 BOOST_PP_ENUM( \
Chris@16 76 BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS, \
Chris@16 77 BOOST_MULTI_INDEX_VARTEMPL_ARG,~)
Chris@16 78
Chris@16 79 #define BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG(z,n,_) \
Chris@16 80 boost::forward<BOOST_PP_CAT(T,n)>(BOOST_PP_CAT(t,n))
Chris@16 81
Chris@16 82 #define BOOST_MULTI_INDEX_FORWARD_PARAM_PACK \
Chris@16 83 BOOST_PP_ENUM( \
Chris@16 84 BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS, \
Chris@16 85 BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG,~)
Chris@16 86
Chris@16 87 namespace boost{namespace multi_index{namespace detail{
Chris@16 88 struct noarg{};
Chris@16 89 }}}
Chris@16 90
Chris@16 91 /* call vartempl function without args */
Chris@16 92
Chris@16 93 #define BOOST_MULTI_INDEX_NULL_PARAM_PACK \
Chris@16 94 BOOST_PP_ENUM_PARAMS( \
Chris@16 95 BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS, \
Chris@16 96 boost::multi_index::detail::noarg() BOOST_PP_INTERCEPT)
Chris@16 97
Chris@16 98 #define BOOST_MULTI_INDEX_TEMPLATE_N(n) \
Chris@16 99 template<BOOST_PP_ENUM_PARAMS(n,typename T)>
Chris@16 100
Chris@16 101 #define BOOST_MULTI_INDEX_TEMPLATE_0(n)
Chris@16 102
Chris@16 103 #define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_AUX(z,n,data) \
Chris@16 104 BOOST_PP_IF(n, \
Chris@16 105 BOOST_MULTI_INDEX_TEMPLATE_N, \
Chris@16 106 BOOST_MULTI_INDEX_TEMPLATE_0)(n) \
Chris@16 107 BOOST_PP_SEQ_ELEM(0,data) /* ret */ \
Chris@16 108 BOOST_PP_SEQ_ELEM(1,data) /* name_from */ ( \
Chris@16 109 BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_ARG,~)) \
Chris@16 110 { \
Chris@16 111 return BOOST_PP_SEQ_ELEM(2,data) /* name_to */ ( \
Chris@16 112 BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG,~) \
Chris@16 113 BOOST_PP_COMMA_IF( \
Chris@16 114 BOOST_PP_AND( \
Chris@16 115 n,BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n))) \
Chris@16 116 BOOST_PP_ENUM_PARAMS( \
Chris@16 117 BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n), \
Chris@16 118 boost::multi_index::detail::noarg() BOOST_PP_INTERCEPT) \
Chris@16 119 ); \
Chris@16 120 }
Chris@16 121
Chris@16 122 #define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( \
Chris@16 123 ret,name_from,name_to) \
Chris@16 124 BOOST_PP_REPEAT_FROM_TO( \
Chris@16 125 0,BOOST_PP_ADD(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,1), \
Chris@16 126 BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_AUX, \
Chris@16 127 (ret)(name_from)(name_to))
Chris@16 128
Chris@16 129 #define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG_AUX( \
Chris@16 130 z,n,data) \
Chris@16 131 BOOST_PP_IF(n, \
Chris@16 132 BOOST_MULTI_INDEX_TEMPLATE_N, \
Chris@16 133 BOOST_MULTI_INDEX_TEMPLATE_0)(n) \
Chris@16 134 BOOST_PP_SEQ_ELEM(0,data) /* ret */ \
Chris@16 135 BOOST_PP_SEQ_ELEM(1,data) /* name_from */ ( \
Chris@16 136 BOOST_PP_SEQ_ELEM(3,data) BOOST_PP_SEQ_ELEM(4,data) /* extra arg */\
Chris@16 137 BOOST_PP_COMMA_IF(n) \
Chris@16 138 BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_ARG,~)) \
Chris@16 139 { \
Chris@16 140 return BOOST_PP_SEQ_ELEM(2,data) /* name_to */ ( \
Chris@16 141 BOOST_PP_SEQ_ELEM(4,data) /* extra_arg_name */ \
Chris@16 142 BOOST_PP_COMMA_IF(n) \
Chris@16 143 BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG,~) \
Chris@16 144 BOOST_PP_COMMA_IF( \
Chris@16 145 BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n)) \
Chris@16 146 BOOST_PP_ENUM_PARAMS( \
Chris@16 147 BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n), \
Chris@16 148 boost::multi_index::detail::noarg() BOOST_PP_INTERCEPT) \
Chris@16 149 ); \
Chris@16 150 }
Chris@16 151
Chris@16 152 #define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG( \
Chris@16 153 ret,name_from,name_to,extra_arg_type,extra_arg_name) \
Chris@16 154 BOOST_PP_REPEAT_FROM_TO( \
Chris@16 155 0,BOOST_PP_ADD(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,1), \
Chris@16 156 BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG_AUX, \
Chris@16 157 (ret)(name_from)(name_to)(extra_arg_type)(extra_arg_name))
Chris@16 158
Chris@16 159 namespace boost{
Chris@16 160
Chris@16 161 namespace multi_index{
Chris@16 162
Chris@16 163 namespace detail{
Chris@16 164
Chris@16 165 #define BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW_AUX(z,n,name) \
Chris@16 166 template< \
Chris@16 167 typename Value \
Chris@16 168 BOOST_PP_COMMA_IF(n) \
Chris@16 169 BOOST_PP_ENUM_PARAMS(n,typename T) \
Chris@16 170 > \
Chris@16 171 Value* name( \
Chris@16 172 Value* x \
Chris@16 173 BOOST_PP_COMMA_IF(n) \
Chris@16 174 BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_ARG,~) \
Chris@16 175 BOOST_PP_COMMA_IF( \
Chris@16 176 BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n)) \
Chris@16 177 BOOST_PP_ENUM_PARAMS( \
Chris@16 178 BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n), \
Chris@16 179 BOOST_FWD_REF(noarg) BOOST_PP_INTERCEPT)) \
Chris@16 180 { \
Chris@16 181 return new(x) Value( \
Chris@16 182 BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG,~)); \
Chris@16 183 }
Chris@16 184
Chris@16 185 #define BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW(name) \
Chris@16 186 BOOST_PP_REPEAT_FROM_TO( \
Chris@16 187 0,BOOST_PP_ADD(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,1), \
Chris@16 188 BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW_AUX, \
Chris@16 189 name)
Chris@16 190
Chris@16 191 BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW(vartempl_placement_new)
Chris@16 192
Chris@16 193 #undef BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW_AUX
Chris@16 194 #undef BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW
Chris@16 195
Chris@16 196 } /* namespace multi_index::detail */
Chris@16 197
Chris@16 198 } /* namespace multi_index */
Chris@16 199
Chris@16 200 } /* namespace boost */
Chris@16 201
Chris@16 202 #else
Chris@16 203
Chris@16 204 /* native variadic templates support */
Chris@16 205
Chris@16 206 #include <utility>
Chris@16 207
Chris@16 208 #define BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK typename... Args
Chris@16 209 #define BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK Args&&... args
Chris@16 210 #define BOOST_MULTI_INDEX_FORWARD_PARAM_PACK std::forward<Args>(args)...
Chris@16 211 #define BOOST_MULTI_INDEX_NULL_PARAM_PACK
Chris@16 212
Chris@16 213 #define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( \
Chris@16 214 ret,name_from,name_to) \
Chris@16 215 template<typename... Args> ret name_from(Args&&... args) \
Chris@16 216 { \
Chris@16 217 return name_to(std::forward<Args>(args)...); \
Chris@16 218 }
Chris@16 219
Chris@16 220 #define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG( \
Chris@16 221 ret,name_from,name_to,extra_arg_type,extra_arg_name) \
Chris@16 222 template<typename... Args> ret name_from( \
Chris@16 223 extra_arg_type extra_arg_name,Args&&... args) \
Chris@16 224 { \
Chris@16 225 return name_to(extra_arg_name,std::forward<Args>(args)...); \
Chris@16 226 }
Chris@16 227
Chris@16 228 namespace boost{
Chris@16 229
Chris@16 230 namespace multi_index{
Chris@16 231
Chris@16 232 namespace detail{
Chris@16 233
Chris@16 234 template<typename Value,typename... Args>
Chris@16 235 Value* vartempl_placement_new(Value*x,Args&&... args)
Chris@16 236 {
Chris@16 237 return new(x) Value(std::forward<Args>(args)...);
Chris@16 238 }
Chris@16 239
Chris@16 240 } /* namespace multi_index::detail */
Chris@16 241
Chris@16 242 } /* namespace multi_index */
Chris@16 243
Chris@16 244 } /* namespace boost */
Chris@16 245
Chris@16 246 #endif
Chris@16 247 #endif