File indexing completed on 2025-01-18 09:38:15
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_HOF_GUARD_CONSTRUCT_H
0009 #define BOOST_HOF_GUARD_CONSTRUCT_H
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090 #include <boost/hof/detail/forward.hpp>
0091 #include <boost/hof/detail/move.hpp>
0092 #include <boost/hof/detail/delegate.hpp>
0093 #include <boost/hof/detail/join.hpp>
0094 #include <boost/hof/detail/remove_rvalue_reference.hpp>
0095 #include <boost/hof/decay.hpp>
0096
0097 #include <initializer_list>
0098
0099 namespace boost { namespace hof {
0100
0101 namespace detail {
0102
0103 template<class T, class=void>
0104 struct construct_f
0105 {
0106 typedef typename std::aligned_storage<sizeof(T)>::type storage;
0107
0108 struct storage_holder
0109 {
0110 storage * s;
0111 storage_holder(storage* x) noexcept : s(x)
0112 {}
0113
0114 T& data() noexcept
0115 {
0116 return *reinterpret_cast<T*>(s);
0117 }
0118
0119 ~storage_holder() noexcept(noexcept(std::declval<T>().~T()))
0120 {
0121 this->data().~T();
0122 }
0123 };
0124
0125 constexpr construct_f() noexcept
0126 {}
0127 template<class... Ts, BOOST_HOF_ENABLE_IF_CONSTRUCTIBLE(T, Ts...)>
0128 T operator()(Ts&&... xs) const BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(T, Ts&&...)
0129 {
0130 storage buffer{};
0131 new(&buffer) T(BOOST_HOF_FORWARD(Ts)(xs)...);
0132 storage_holder h(&buffer);
0133 return boost::hof::move(h.data());
0134 }
0135
0136 template<class X, BOOST_HOF_ENABLE_IF_CONSTRUCTIBLE(T, std::initializer_list<X>&&)>
0137 T operator()(std::initializer_list<X>&& x) const BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(T, std::initializer_list<X>&&)
0138 {
0139 storage buffer{};
0140 new(&buffer) T(static_cast<std::initializer_list<X>&&>(x));
0141 storage_holder h(&buffer);
0142 return h.data();
0143 }
0144
0145 template<class X, BOOST_HOF_ENABLE_IF_CONSTRUCTIBLE(T, std::initializer_list<X>&)>
0146 T operator()(std::initializer_list<X>& x) const BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(T, std::initializer_list<X>&)
0147 {
0148 storage buffer{};
0149 new(&buffer) T(x);
0150 storage_holder h(&buffer);
0151 return h.data();
0152 }
0153
0154 template<class X, BOOST_HOF_ENABLE_IF_CONSTRUCTIBLE(T, const std::initializer_list<X>&)>
0155 T operator()(const std::initializer_list<X>& x) const BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(T, const std::initializer_list<X>&)
0156 {
0157 storage buffer{};
0158 new(&buffer) T(x);
0159 storage_holder h(&buffer);
0160 return h.data();
0161 }
0162 };
0163
0164 template<class T>
0165 struct construct_f<T, typename std::enable_if<BOOST_HOF_IS_LITERAL(T)>::type>
0166 {
0167 constexpr construct_f() noexcept
0168 {}
0169 template<class... Ts, BOOST_HOF_ENABLE_IF_CONSTRUCTIBLE(T, Ts...)>
0170 constexpr T operator()(Ts&&... xs) const noexcept
0171 {
0172 return T(BOOST_HOF_FORWARD(Ts)(xs)...);
0173 }
0174
0175 template<class X, BOOST_HOF_ENABLE_IF_CONSTRUCTIBLE(T, std::initializer_list<X>&&)>
0176 constexpr T operator()(std::initializer_list<X>&& x) const noexcept
0177 {
0178 return T(static_cast<std::initializer_list<X>&&>(x));
0179 }
0180
0181 template<class X, BOOST_HOF_ENABLE_IF_CONSTRUCTIBLE(T, std::initializer_list<X>&)>
0182 constexpr T operator()(std::initializer_list<X>& x) const noexcept
0183 {
0184 return T(x);
0185 }
0186
0187 template<class X, BOOST_HOF_ENABLE_IF_CONSTRUCTIBLE(T, const std::initializer_list<X>&)>
0188 constexpr T operator()(const std::initializer_list<X>& x) const noexcept
0189 {
0190 return T(x);
0191 }
0192 };
0193
0194 template<template<class...> class Template, template<class...> class D>
0195 struct construct_template_f
0196 {
0197 constexpr construct_template_f() noexcept
0198 {}
0199 template<class... Ts, class Result=BOOST_HOF_JOIN(Template, typename D<Ts>::type...),
0200 BOOST_HOF_ENABLE_IF_CONSTRUCTIBLE(Result, Ts...)>
0201 constexpr Result operator()(Ts&&... xs) const BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(Result, Ts&&...)
0202 {
0203 return construct_f<Result>()(BOOST_HOF_FORWARD(Ts)(xs)...);
0204 }
0205 };
0206
0207 template<class MetafunctionClass>
0208 struct construct_meta_f
0209 {
0210 constexpr construct_meta_f() noexcept
0211 {}
0212
0213 template<class... Ts>
0214 struct apply
0215 : MetafunctionClass::template apply<Ts...>
0216 {};
0217
0218 template<class... Ts,
0219 class Metafunction=BOOST_HOF_JOIN(apply, Ts...),
0220 class Result=typename Metafunction::type,
0221 BOOST_HOF_ENABLE_IF_CONSTRUCTIBLE(Result, Ts...)>
0222 constexpr Result operator()(Ts&&... xs) const BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(Result, Ts&&...)
0223 {
0224 return construct_f<Result>()(BOOST_HOF_FORWARD(Ts)(xs)...);
0225 }
0226 };
0227
0228 template<template<class...> class MetafunctionTemplate>
0229 struct construct_meta_template_f
0230 {
0231 constexpr construct_meta_template_f() noexcept
0232 {}
0233 template<class... Ts,
0234 class Metafunction=BOOST_HOF_JOIN(MetafunctionTemplate, Ts...),
0235 class Result=typename Metafunction::type,
0236 BOOST_HOF_ENABLE_IF_CONSTRUCTIBLE(Result, Ts...)>
0237 constexpr Result operator()(Ts&&... xs) const BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(Result, Ts&&...)
0238 {
0239 return construct_f<Result>()(BOOST_HOF_FORWARD(Ts)(xs)...);
0240 }
0241 };
0242
0243
0244 template<class T>
0245 struct construct_id
0246 {
0247 typedef T type;
0248 };
0249
0250 }
0251
0252 template<class T>
0253 constexpr detail::construct_f<T> construct() noexcept
0254 {
0255 return {};
0256 }
0257
0258 template<class T>
0259 constexpr detail::construct_f<T> construct_forward() noexcept
0260 {
0261 return {};
0262 }
0263
0264 template<class T>
0265 constexpr detail::construct_f<T> construct_basic() noexcept
0266 {
0267 return {};
0268 }
0269
0270 template<template<class...> class Template>
0271 constexpr detail::construct_template_f<Template, detail::decay_mf> construct() noexcept
0272 {
0273 return {};
0274 }
0275
0276 template<template<class...> class Template>
0277 constexpr detail::construct_template_f<Template, detail::construct_id> construct_forward() noexcept
0278 {
0279 return {};
0280 }
0281
0282 template<template<class...> class Template>
0283 constexpr detail::construct_template_f<Template, detail::remove_rvalue_reference> construct_basic() noexcept
0284 {
0285 return {};
0286 }
0287
0288 template<class T>
0289 constexpr detail::construct_meta_f<T> construct_meta() noexcept
0290 {
0291 return {};
0292 }
0293
0294 template<template<class...> class Template>
0295 constexpr detail::construct_meta_template_f<Template> construct_meta() noexcept
0296 {
0297 return {};
0298 }
0299
0300 }}
0301
0302 #endif