diff --git a/sprout/config.hpp b/sprout/config.hpp index 3a77601b..85ad4ed2 100644 --- a/sprout/config.hpp +++ b/sprout/config.hpp @@ -3,9 +3,11 @@ #ifndef SPROUT_CONFIG_DISABLE_CONSTEXPR # define SPROUT_CONSTEXPR constexpr +# define SPROUT_CONSTEXPR_OR_CONST constexpr # define SPROUT_STATIC_CONSTEXPR static constexpr #else // #ifndef SPROUT_CONFIG_DISABLE_CONSTEXPR # define SPROUT_CONSTEXPR +# define SPROUT_CONSTEXPR_OR_CONST const # define SPROUT_STATIC_CONSTEXPR static const #endif // #ifndef SPROUT_CONFIG_DISABLE_CONSTEXPR @@ -30,9 +32,9 @@ #endif // #ifndef SPROUT_CONFIG_DISABLE_USER_DEFINED_LITERALS #ifndef SPROUT_CONFIG_USE_SSCRISK_CEL -# define HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT +# define HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT # define HDR_ALGORITHM_SSCRISK_CEL_OR_SPROUT -# define HDR_ITERATOR_SSCRISK_CEL_OR_SPROUT +# define HDR_ITERATOR_SSCRISK_CEL_OR_SPROUT # define NS_SSCRISK_CEL_OR_SPROUT sprout #else // #ifndef SPROUT_CONFIG_USE_SSCRISK_CEL # define HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT diff --git a/sprout/functional.hpp b/sprout/functional.hpp index a32beb75..9e82781a 100644 --- a/sprout/functional.hpp +++ b/sprout/functional.hpp @@ -2,9 +2,11 @@ #define SPROUT_FUNCTIONAL_HPP #include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #endif // #ifndef SPROUT_FUNCTIONAL_HPP diff --git a/sprout/functional/base.hpp b/sprout/functional/base.hpp new file mode 100644 index 00000000..69c79821 --- /dev/null +++ b/sprout/functional/base.hpp @@ -0,0 +1,8 @@ +#ifndef SPROUT_FUNCTIONAL_BASE_HPP +#define SPROUT_FUNCTIONAL_BASE_HPP + +#include +#include +#include + +#endif // #ifndef SPROUT_FUNCTIONAL_BASE_HPP diff --git a/sprout/functional/binary_function.hpp b/sprout/functional/binary_function.hpp new file mode 100644 index 00000000..93e2d735 --- /dev/null +++ b/sprout/functional/binary_function.hpp @@ -0,0 +1,19 @@ +#ifndef SPROUT_FUNCTIONAL_BINARY_FUNCTION_HPP +#define SPROUT_FUNCTIONAL_BINARY_FUNCTION_HPP + +#include + +namespace sprout { + // + // binary_function + // + template + struct binary_function { + public: + typedef Arg1 first_argument_type; + typedef Arg2 second_argument_type; + typedef Result result_type; + }; +} // namespace sprout + +#endif // #ifndef SPROUT_FUNCTIONAL_BINARY_FUNCTION_HPP diff --git a/sprout/functional/bind.hpp b/sprout/functional/bind.hpp new file mode 100644 index 00000000..022187b2 --- /dev/null +++ b/sprout/functional/bind.hpp @@ -0,0 +1,7 @@ +#ifndef SPROUT_FUNCTIONAL_BIND_HPP +#define SPROUT_FUNCTIONAL_BIND_HPP + +#include +#include + +#endif // #ifndef SPROUT_FUNCTIONAL_BIND_HPP diff --git a/sprout/functional/bind/bind.hpp b/sprout/functional/bind/bind.hpp new file mode 100644 index 00000000..274f21a1 --- /dev/null +++ b/sprout/functional/bind/bind.hpp @@ -0,0 +1,541 @@ +#ifndef SPROUT_FUNCTIONAL_BIND_BIND_HPP +#define SPROUT_FUNCTIONAL_BIND_BIND_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + // 20.8.9 bind + + template + struct is_bind_expression + : public std::false_type + {}; + template + struct is_bind_expression + : public sprout::is_bind_expression + {}; + + template + struct is_placeholder + : public std::integral_constant + {}; + template + struct is_placeholder + : public sprout::is_placeholder + {}; + + // + // placeholder + // + template + struct placeholder {}; + + namespace placeholders { + SPROUT_STATIC_CONSTEXPR sprout::placeholder<1> _1; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<2> _2; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<3> _3; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<4> _4; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<5> _5; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<6> _6; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<7> _7; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<8> _8; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<9> _9; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<10> _10; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<11> _11; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<12> _12; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<13> _13; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<14> _14; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<15> _15; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<16> _16; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<17> _17; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<18> _18; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<19> _19; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<20> _20; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<21> _21; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<22> _22; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<23> _23; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<24> _24; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<25> _25; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<26> _26; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<27> _27; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<28> _28; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<29> _29; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<30> _30; + } // namespace placeholders + using sprout::placeholders::_1; + using sprout::placeholders::_2; + using sprout::placeholders::_3; + using sprout::placeholders::_4; + using sprout::placeholders::_5; + using sprout::placeholders::_6; + using sprout::placeholders::_7; + using sprout::placeholders::_8; + using sprout::placeholders::_9; + using sprout::placeholders::_10; + using sprout::placeholders::_11; + using sprout::placeholders::_12; + using sprout::placeholders::_13; + using sprout::placeholders::_14; + using sprout::placeholders::_15; + using sprout::placeholders::_16; + using sprout::placeholders::_17; + using sprout::placeholders::_18; + using sprout::placeholders::_19; + using sprout::placeholders::_20; + using sprout::placeholders::_21; + using sprout::placeholders::_2; + using sprout::placeholders::_23; + using sprout::placeholders::_24; + using sprout::placeholders::_25; + using sprout::placeholders::_26; + using sprout::placeholders::_27; + using sprout::placeholders::_28; + using sprout::placeholders::_29; + using sprout::placeholders::_30; + + template + struct is_placeholder > + : public std::integral_constant + {}; + + namespace detail { + struct no_tuple_element; + + template + struct safe_tuple_element_impl + : tuple_element + {}; + template + struct safe_tuple_element_impl { + public: + typedef sprout::detail::no_tuple_element type; + }; + template + struct safe_tuple_element + : public sprout::detail::safe_tuple_element_impl::value)> + {}; + + template< + typename Arg, + bool IsBindExp = sprout::is_bind_expression::value, + bool IsPlaceholder = (sprout::is_placeholder::value > 0) + > + class mu; + template + class mu, false, false> { + public: + typedef T& result_type; + public: + template + SPROUT_CONSTEXPR result_type operator()(CVRef& arg, Tuple&) const volatile { + // !!! + //return arg.get(); + return const_cast::type>::type&>(arg).get(); + } + }; + template + class mu { + private: + template + SPROUT_CONSTEXPR auto call( + CVArg& arg, + sprout::tuples::tuple& tuple, + sprout::index_tuple + ) const volatile + -> decltype(arg(std::declval()...)) + { + return arg(sprout::forward(sprout::tuples::get(tuple))...); + } + public: + template + SPROUT_CONSTEXPR auto operator()(CVArg& arg, sprout::tuples::tuple& tuple) const volatile + -> decltype(arg(std::declval()...)) + { + return call(arg, tuple, typename sprout::index_range<0, sizeof...(Args)>::type()); + } + }; + template + class mu { + public: + template + class result; + template + class result { + private: + typedef typename sprout::detail::safe_tuple_element< + (sprout::is_placeholder::value - 1), + Tuple + >::type base_type; + public: + typedef typename std::add_rvalue_reference::type type; + }; + public: + template + typename result::type + SPROUT_CONSTEXPR operator()(Arg const volatile&, Tuple& tuple) const volatile { + return sprout::forward::type>( + sprout::tuples::get<(sprout::is_placeholder::value - 1)>(tuple) + ); + } + }; + template + class mu { + public: + template + struct result; + template + struct result { + public: + typedef typename std::add_lvalue_reference::type type; + }; + public: + template + SPROUT_CONSTEXPR CVArg&& operator()(CVArg&& arg, Tuple&) const volatile { + return sprout::forward(arg); + } + }; + + template + struct maybe_wrap_member_pointer { + public: + typedef T type; + public: + static SPROUT_CONSTEXPR T const& do_wrap(T const& x) { + return x; + } + static SPROUT_CONSTEXPR T&& do_wrap(T&& x) { + return static_cast(x); + } + }; + template + struct maybe_wrap_member_pointer { + public: + typedef sprout::mem_fn_adaptor type; + public: + static SPROUT_CONSTEXPR type do_wrap(T Class::* pm) { + return type(pm); + } + }; + template<> + struct maybe_wrap_member_pointer { + public: + typedef void type; + }; + + template + inline auto volget(sprout::tuples::tuple volatile& tuple) + -> typename sprout::tuples::tuple_element >::type volatile& + { + return sprout::tuples::get(const_cast&>(tuple)); + } + template + inline SPROUT_CONSTEXPR auto volget(sprout::tuples::tuple const volatile& tuple) + -> typename sprout::tuples::tuple_element >::type const volatile& + { + return sprout::tuples::get(const_cast const&>(tuple)); + } + } // namespace detail + + // + // binder + // + template + struct binder; + template + class binder + : public sprout::weak_result_type + { + private: + typedef binder self_type; + typedef typename sprout::index_range<0, sizeof...(BoundArgs)>::type bound_indexes; + private: + Functor f_; + sprout::tuples::tuple bound_args_; + private: + template + Result call(sprout::tuples::tuple&& args, sprout::index_tuple) { + return f_(sprout::detail::mu()(sprout::tuples::get(bound_args_), args)...); + } + template + SPROUT_CONSTEXPR Result call_c(sprout::tuples::tuple&& args, sprout::index_tuple) const { + return f_(sprout::detail::mu()(sprout::tuples::get(bound_args_), args)...); + } + template + Result call_v(sprout::tuples::tuple&& args, sprout::index_tuple) volatile { + return f_(sprout::detail::mu()(sprout::detail::volget(bound_args_), args)...); + } + template + SPROUT_CONSTEXPR Result call_cv(sprout::tuples::tuple&& args, sprout::index_tuple) const volatile { + return f_(sprout::detail::mu()(sprout::detail::volget(bound_args_), args)...); + } + public: + template + explicit SPROUT_CONSTEXPR binder(Functor const& f, Args&&... args) + : f_(f) + , bound_args_(sprout::forward(args)...) + {} + binder(binder const&) = default; + template< + typename... Args, + typename Result = decltype( + std::declval()( + sprout::detail::mu()( + std::declval(), + std::declval&>() + )... + ) + ) + > + Result operator()(Args&&... args) { + return call( + sprout::tuples::forward_as_tuple(sprout::forward(args)...), + bound_indexes() + ); + } + template< + typename... Args, + typename Result = decltype( + std::declval= 0), typename std::add_const::type>::type>()( + sprout::detail::mu()( + std::declval(), + std::declval&>() + )... + ) + ) + > + SPROUT_CONSTEXPR Result operator()(Args&&... args) const { + return call_c( + sprout::tuples::forward_as_tuple(sprout::forward(args)...), + bound_indexes() + ); + } + template< + typename... Args, + typename Result = decltype( + std::declval= 0), typename std::add_volatile::type>::type>()( + sprout::detail::mu()( + std::declval(), + std::declval&>() + )... + ) + ) + > + Result operator()(Args&&... args) volatile { + return call_v( + sprout::tuples::forward_as_tuple(sprout::forward(args)...), + bound_indexes() + ); + } + + template< + typename... Args, + typename Result = decltype( + std::declval= 0), typename std::add_cv::type>::type>()( + sprout::detail::mu()( + std::declval(), + std::declval&>() + )... + ) + ) + > + SPROUT_CONSTEXPR Result operator()(Args&&... args) const volatile { + return call_cv( + sprout::tuples::forward_as_tuple(sprout::forward(args)...), + bound_indexes() + ); + } + }; + + // + // bind_result + // + template + struct bind_result; + template + class bind_result { + private: + typedef bind_result self_type; + typedef typename sprout::index_range<0, sizeof...(BoundArgs)>::type bound_indexes; + private: + template + struct enable_if_void + : public std::enable_if::value, int> + {}; + template + struct disable_if_void + : public std::enable_if::value, int> + {}; + private: + Functor f_; + sprout::tuples::tuple bound_args_; + private: + template + Result call( + sprout::tuples::tuple&& args, + sprout::index_tuple, + typename disable_if_void::type = 0 + ) + { + return f_(sprout::detail::mu()(sprout::tuples::get(bound_args_), args)...); + } + template + Result call( + sprout::tuples::tuple&& args, + sprout::index_tuple, + typename enable_if_void::type = 0 + ) + { + f_(sprout::detail::mu()(get(bound_args_), args)...); + } + template + SPROUT_CONSTEXPR Result call( + sprout::tuples::tuple&& args, + sprout::index_tuple, + typename disable_if_void::type = 0 + ) const + { + return f_(sprout::detail::mu()(sprout::tuples::get(bound_args_), args)...); + } + template + Result call( + sprout::tuples::tuple&& args, + sprout::index_tuple, + typename enable_if_void::type = 0 + ) const + { + f_(sprout::detail::mu()(sprout::tuples::get(bound_args_), args)...); + } + template + Result call( + sprout::tuples::tuple&& args, + sprout::index_tuple, + typename disable_if_void::type = 0 + ) volatile + { + return f_(sprout::detail::mu()(sprout::detail::volget(bound_args_), args)...); + } + template + Result call( + sprout::tuples::tuple&& args, + sprout::index_tuple, + typename enable_if_void::type = 0 + ) volatile + { + f_(sprout::detail::mu()(sprout::detail::volget(bound_args_), args)...); + } + template + SPROUT_CONSTEXPR Result call( + sprout::tuples::tuple&& args, + sprout::index_tuple, + typename disable_if_void::type = 0 + ) const volatile + { + return f_(sprout::detail::mu()(sprout::detail::volget(bound_args_), args)...); + } + template + Result call( + sprout::tuples::tuple&& args, + sprout::index_tuple, + typename enable_if_void::type = 0 + ) const volatile + { + f_(sprout::detail::mu()(sprout::detail::volget(bound_args_), args)...); + } + public: + typedef Result result_type; + template + explicit bind_result(Functor const& f, Args&&... args) + : f_(f) + , bound_args_(sprout::forward(args)...) + {} + bind_result(bind_result const&) = default; + template + result_type operator()(Args&&... args) { + return call( + sprout::tuples::forward_as_tuple(sprout::forward(args)...), + bound_indexes() + ); + } + template + SPROUT_CONSTEXPR result_type operator()(Args&&... args) const { + return call( + sprout::tuples::forward_as_tuple(sprout::forward(args)...), + bound_indexes() + ); + } + template + result_type operator()(Args&&... args) volatile { + return call( + sprout::tuples::forward_as_tuple(sprout::forward(args)...), + bound_indexes() + ); + } + template + SPROUT_CONSTEXPR result_type operator()(Args&&... args) const volatile { + return call( + sprout::tuples::forward_as_tuple(sprout::forward(args)...), + bound_indexes() + ); + } + }; + + template + struct is_bind_expression > + : public std::true_type + {}; + template + struct is_bind_expression > + : public std::true_type + {}; + + namespace detail { + template + struct bind_helper { + public: + typedef sprout::detail::maybe_wrap_member_pointer::type> maybe_type; + typedef typename maybe_type::type func_type; + typedef sprout::binder::type...)> type; + }; + + template + struct bindres_helper { + public: + typedef sprout::detail::maybe_wrap_member_pointer::type> maybe_type; + typedef typename maybe_type::type functor_type; + typedef sprout::bind_result::type...)> type; + }; + } // namespace detail + + // + // bind + // + template + inline SPROUT_CONSTEXPR typename sprout::detail::bind_helper::type + bind(F&& f, BoundArgs&&... args) { + typedef sprout::detail::bind_helper helper_type; + typedef typename helper_type::maybe_type maybe_type; + typedef typename helper_type::type result_type; + return result_type(maybe_type::do_wrap(sprout::forward(f)), sprout::forward(args)...); + } + template + inline SPROUT_CONSTEXPR typename sprout::detail::bindres_helper::type + bind(F&& f, BoundArgs&&... args) { + typedef sprout::detail::bindres_helper helper_type; + typedef typename helper_type::maybe_type maybe_type; + typedef typename helper_type::type result_type; + return result_type(maybe_type::do_wrap(sprout::forward(f)), sprout::forward(args)...); + } +} // namespace sprout + +#endif // #ifndef SPROUT_FUNCTIONAL_BIND_BIND_HPP diff --git a/sprout/functional/binder.hpp b/sprout/functional/binder.hpp new file mode 100644 index 00000000..01d54f54 --- /dev/null +++ b/sprout/functional/binder.hpp @@ -0,0 +1,8 @@ +#ifndef SPROUT_FUNCTIONAL_BINDER_HPP +#define SPROUT_FUNCTIONAL_BINDER_HPP + +#include +#include +#include + +#endif // #ifndef SPROUT_FUNCTIONAL_BINDER_HPP diff --git a/sprout/functional/bit_and.hpp b/sprout/functional/bit_and.hpp new file mode 100644 index 00000000..21226b87 --- /dev/null +++ b/sprout/functional/bit_and.hpp @@ -0,0 +1,21 @@ +#ifndef SPROUT_FUNCTIONAL_BIT_AND_HPP +#define SPROUT_FUNCTIONAL_BIT_AND_HPP + +#include + +namespace sprout { + // 20.8.7 bitwise operations + template + struct bit_and { + public: + typedef T first_argument_type; + typedef T second_argument_type; + typedef T result_type; + public: + SPROUT_CONSTEXPR T operator()(T const& x, T const& y) const { + return x & y; + } + }; +} // namespace sprout + +#endif // #ifndef SPROUT_FUNCTIONAL_BIT_AND_HPP diff --git a/sprout/functional/bit_not.hpp b/sprout/functional/bit_not.hpp new file mode 100644 index 00000000..a843bf5d --- /dev/null +++ b/sprout/functional/bit_not.hpp @@ -0,0 +1,20 @@ +#ifndef SPROUT_FUNCTIONAL_BIT_NOT_HPP +#define SPROUT_FUNCTIONAL_BIT_NOT_HPP + +#include + +namespace sprout { + // 20.8.7 bitwise operations + template + struct bit_not { + public: + typedef T argument_type; + typedef T result_type; + public: + SPROUT_CONSTEXPR T operator()(T const& x) const { + return !x; + } + }; +} // namespace sprout + +#endif // #ifndef SPROUT_FUNCTIONAL_BIT_NOT_HPP diff --git a/sprout/functional/bit_or.hpp b/sprout/functional/bit_or.hpp new file mode 100644 index 00000000..30b3b036 --- /dev/null +++ b/sprout/functional/bit_or.hpp @@ -0,0 +1,21 @@ +#ifndef SPROUT_FUNCTIONAL_BIT_OR_HPP +#define SPROUT_FUNCTIONAL_BIT_OR_HPP + +#include + +namespace sprout { + // 20.8.7 bitwise operations + template + struct bit_or { + public: + typedef T first_argument_type; + typedef T second_argument_type; + typedef T result_type; + public: + SPROUT_CONSTEXPR T operator()(T const& x, T const& y) const { + return x | y; + } + }; +} // namespace sprout + +#endif // #ifndef SPROUT_FUNCTIONAL_BIT_OR_HPP diff --git a/sprout/functional/bit_xor.hpp b/sprout/functional/bit_xor.hpp new file mode 100644 index 00000000..230e7cab --- /dev/null +++ b/sprout/functional/bit_xor.hpp @@ -0,0 +1,21 @@ +#ifndef SPROUT_FUNCTIONAL_BIT_XOR_HPP +#define SPROUT_FUNCTIONAL_BIT_XOR_HPP + +#include + +namespace sprout { + // 20.8.7 bitwise operations + template + struct bit_xor { + public: + typedef T first_argument_type; + typedef T second_argument_type; + typedef T result_type; + public: + SPROUT_CONSTEXPR T operator()(T const& x, T const& y) const { + return x ^ y; + } + }; +} // namespace sprout + +#endif // #ifndef SPROUT_FUNCTIONAL_BIT_XOR_HPP diff --git a/sprout/functional/bitwise.hpp b/sprout/functional/bitwise.hpp new file mode 100644 index 00000000..97cf269a --- /dev/null +++ b/sprout/functional/bitwise.hpp @@ -0,0 +1,9 @@ +#ifndef SPROUT_FUNCTIONAL_BITWISE_HPP +#define SPROUT_FUNCTIONAL_BITWISE_HPP + +#include +#include +#include +#include + +#endif // #ifndef SPROUT_FUNCTIONAL_BITWISE_HPP diff --git a/sprout/functional/functor.hpp b/sprout/functional/functor.hpp new file mode 100644 index 00000000..93ed34c9 --- /dev/null +++ b/sprout/functional/functor.hpp @@ -0,0 +1,12 @@ +#ifndef SPROUT_FUNCTIONAL_FUNCTOR_HPP +#define SPROUT_FUNCTIONAL_FUNCTOR_HPP + +#include +#include +#include +#include +#include +#include +#include + +#endif // #ifndef SPROUT_FUNCTIONAL_FUNCTOR_HPP diff --git a/sprout/functional/hash/hash.hpp b/sprout/functional/hash/hash.hpp index 6a127d9f..804ac9de 100644 --- a/sprout/functional/hash/hash.hpp +++ b/sprout/functional/hash/hash.hpp @@ -13,9 +13,11 @@ namespace sprout { // inline SPROUT_CONSTEXPR std::size_t hash_value(bool v); inline SPROUT_CONSTEXPR std::size_t hash_value(char v); - inline SPROUT_CONSTEXPR std::size_t hash_value(wchar_t v); inline SPROUT_CONSTEXPR std::size_t hash_value(unsigned char v); inline SPROUT_CONSTEXPR std::size_t hash_value(signed char v); + inline SPROUT_CONSTEXPR std::size_t hash_value(char16_t v); + inline SPROUT_CONSTEXPR std::size_t hash_value(char32_t v); + inline SPROUT_CONSTEXPR std::size_t hash_value(wchar_t v); inline SPROUT_CONSTEXPR std::size_t hash_value(short v); inline SPROUT_CONSTEXPR std::size_t hash_value(unsigned short v); inline SPROUT_CONSTEXPR std::size_t hash_value(int v); @@ -103,15 +105,21 @@ namespace sprout { inline SPROUT_CONSTEXPR std::size_t hash_value(char v) { return static_cast(v); } - inline SPROUT_CONSTEXPR std::size_t hash_value(wchar_t v) { - return static_cast(v); - } inline SPROUT_CONSTEXPR std::size_t hash_value(unsigned char v) { return static_cast(v); } inline SPROUT_CONSTEXPR std::size_t hash_value(signed char v) { return static_cast(v); } + inline SPROUT_CONSTEXPR std::size_t hash_value(char16_t v) { + return static_cast(v); + } + inline SPROUT_CONSTEXPR std::size_t hash_value(char32_t v) { + return static_cast(v); + } + inline SPROUT_CONSTEXPR std::size_t hash_value(wchar_t v) { + return static_cast(v); + } inline SPROUT_CONSTEXPR std::size_t hash_value(short v) { return static_cast(v); } @@ -216,9 +224,11 @@ namespace sprout { SPROUT_HASH_SPECIALIZE(bool); SPROUT_HASH_SPECIALIZE(char); - SPROUT_HASH_SPECIALIZE(wchar_t); SPROUT_HASH_SPECIALIZE(signed char); SPROUT_HASH_SPECIALIZE(unsigned char); + SPROUT_HASH_SPECIALIZE(char16_t); + SPROUT_HASH_SPECIALIZE(char32_t); + SPROUT_HASH_SPECIALIZE(wchar_t); SPROUT_HASH_SPECIALIZE(short); SPROUT_HASH_SPECIALIZE(unsigned short); SPROUT_HASH_SPECIALIZE(int); diff --git a/sprout/functional/logical.hpp b/sprout/functional/logical.hpp new file mode 100644 index 00000000..cac263a5 --- /dev/null +++ b/sprout/functional/logical.hpp @@ -0,0 +1,9 @@ +#ifndef SPROUT_FUNCTIONAL_LOGICAL_HPP +#define SPROUT_FUNCTIONAL_LOGICAL_HPP + +#include +#include +#include +#include + +#endif // #ifndef SPROUT_FUNCTIONAL_LOGICAL_HPP diff --git a/sprout/functional/logical_and.hpp b/sprout/functional/logical_and.hpp new file mode 100644 index 00000000..449d0df4 --- /dev/null +++ b/sprout/functional/logical_and.hpp @@ -0,0 +1,21 @@ +#ifndef SPROUT_FUNCTIONAL_LOGICAL_AND_HPP +#define SPROUT_FUNCTIONAL_LOGICAL_AND_HPP + +#include + +namespace sprout { + // 20.8.6 logical operations + template + struct logical_and { + public: + typedef T first_argument_type; + typedef T second_argument_type; + typedef bool result_type; + public: + SPROUT_CONSTEXPR bool operator()(T const& x, T const& y) const { + return x && y; + } + }; +} // namespace sprout + +#endif // #ifndef SPROUT_FUNCTIONAL_LOGICAL_AND_HPP diff --git a/sprout/functional/logical_not.hpp b/sprout/functional/logical_not.hpp new file mode 100644 index 00000000..c802837d --- /dev/null +++ b/sprout/functional/logical_not.hpp @@ -0,0 +1,20 @@ +#ifndef SPROUT_FUNCTIONAL_LOGICAL_NOT_HPP +#define SPROUT_FUNCTIONAL_LOGICAL_NOT_HPP + +#include + +namespace sprout { + // 20.8.6 logical operations + template + struct logical_not { + public: + typedef T argument_type; + typedef bool result_type; + public: + SPROUT_CONSTEXPR bool operator()(T const& x) const { + return !x; + } + }; +} // namespace sprout + +#endif // #ifndef SPROUT_FUNCTIONAL_LOGICAL_NOT_HPP diff --git a/sprout/functional/logical_or.hpp b/sprout/functional/logical_or.hpp new file mode 100644 index 00000000..79479b4e --- /dev/null +++ b/sprout/functional/logical_or.hpp @@ -0,0 +1,21 @@ +#ifndef SPROUT_FUNCTIONAL_LOGICAL_OR_HPP +#define SPROUT_FUNCTIONAL_LOGICAL_OR_HPP + +#include + +namespace sprout { + // 20.8.6 logical operations + template + struct logical_or { + public: + typedef T first_argument_type; + typedef T second_argument_type; + typedef bool result_type; + public: + SPROUT_CONSTEXPR bool operator()(T const& x, T const& y) const { + return x || y; + } + }; +} // namespace sprout + +#endif // #ifndef SPROUT_FUNCTIONAL_LOGICAL_OR_HPP diff --git a/sprout/functional/mem_fn.hpp b/sprout/functional/mem_fn.hpp new file mode 100644 index 00000000..08cb9cff --- /dev/null +++ b/sprout/functional/mem_fn.hpp @@ -0,0 +1,268 @@ +#ifndef SPROUT_FUNCTIONAL_MEM_FN_HPP +#define SPROUT_FUNCTIONAL_MEM_FN_HPP + +#include +#include +#include +#include + +namespace sprout { + // 20.8.10 member function adaptors + + namespace detail { + template + struct maybe_unary_or_binary_function {}; + template + struct maybe_unary_or_binary_function + : public std::unary_function + {}; + template + struct maybe_unary_or_binary_function + : public std::binary_function + {}; + + template + struct mem_fn_const_or_non { + public: + typedef T const& type; + }; + template + struct mem_fn_const_or_non { + public: + typedef T& type; + }; + } // namespace detail + + // + // mem_fn_adaptor + // + template + class mem_fn_adaptor; + template + class mem_fn_adaptor + : public sprout::detail::maybe_unary_or_binary_function + { + public: + typedef Res result_type; + private: + typedef Res (Class::*functor)(Args...); + private: + functor pmf_; + private: + template + Res call(T& object, Class const volatile*, Args... args) const { + return (object.*pmf_)(sprout::forward(args)...); + } + template + Res call(T& ptr, void const volatile*, Args... args) const { + return ((*ptr).*pmf_)(sprout::forward(args)...); + } + public: + explicit SPROUT_CONSTEXPR mem_fn_adaptor(functor pmf) + : pmf_(pmf) + {} + Res operator()(Class& object, Args... args) const { + return (object.*pmf_)(sprout::forward(args)...); + } + Res operator()(Class* object, Args... args) const { + return (object->*pmf_)(sprout::forward(args)...); + } + template + Res operator()(T& object, Args... args) const { + return call(object, &object, sprout::forward(args)...); + } + }; + template + class mem_fn_adaptor + : public sprout::detail::maybe_unary_or_binary_function + { + public: + typedef Res result_type; + private: + typedef Res (Class::*functor)(Args...) const; + private: + functor pmf_; + private: + template + SPROUT_CONSTEXPR Res call(T const& object, Class const volatile*, Args... args) const { + return (object.*pmf_)(sprout::forward(args)...); + } + template + SPROUT_CONSTEXPR Res call(T const& ptr, void const volatile*, Args... args) const { + return ((*ptr).*pmf_)(sprout::forward(args)...); + } + public: + explicit SPROUT_CONSTEXPR mem_fn_adaptor(functor pmf) + : pmf_(pmf) + {} + SPROUT_CONSTEXPR Res operator()(Class const& object, Args... args) const { + return (object.*pmf_)(sprout::forward(args)...); + } + SPROUT_CONSTEXPR Res operator()(Class const* object, Args... args) const { + return (object->*pmf_)(sprout::forward(args)...); + } + template + SPROUT_CONSTEXPR Res operator()(T const& object, Args... args) const { + return call(object, &object, sprout::forward(args)...); + } + }; + template + class mem_fn_adaptor + : public sprout::detail::maybe_unary_or_binary_function + { + public: + typedef Res result_type; + private: + typedef Res (Class::*functor)(Args...) volatile; + private: + functor pmf_; + private: + template + Res call(T& object, Class const volatile*, Args... args) const { + return (object.*pmf_)(sprout::forward(args)...); + } + template + Res call(T& ptr, void const volatile*, Args... args) const { + return ((*ptr).*pmf_)(sprout::forward(args)...); + } + public: + explicit SPROUT_CONSTEXPR mem_fn_adaptor(functor pmf) + : pmf_(pmf) + {} + Res operator()(Class volatile& object, Args... args) const { + return (object.*pmf_)(sprout::forward(args)...); + } + Res operator()(Class volatile* object, Args... args) const { + return (object->*pmf_)(sprout::forward(args)...); + } + template + Res operator()(T& object, Args... args) const { + return call(object, &object, sprout::forward(args)...); + } + }; + template + class mem_fn_adaptor + : public sprout::detail::maybe_unary_or_binary_function + { + public: + typedef Res result_type; + private: + typedef Res (Class::*functor)(Args...) const volatile; + private: + functor pmf_; + private: + template + SPROUT_CONSTEXPR Res call(T const& object, Class const volatile*, Args... args) const { + return (object.*pmf_)(sprout::forward(args)...); + } + template + SPROUT_CONSTEXPR Res call(T const& ptr, void const volatile*, Args... args) const { + return ((*ptr).*pmf_)(sprout::forward(args)...); + } + public: + explicit SPROUT_CONSTEXPR mem_fn_adaptor(functor pmf) + : pmf_(pmf) + {} + SPROUT_CONSTEXPR Res operator()(Class const volatile& object, Args... args) const { + return (object.*pmf_)(sprout::forward(args)...); + } + SPROUT_CONSTEXPR Res operator()(Class const volatile* object, Args... args) const { + return (object->*pmf_)(sprout::forward(args)...); + } + template + SPROUT_CONSTEXPR Res operator()(T const& object, Args... args) const { + return call(object, &object, sprout::forward(args)...); + } + }; + + template + class mem_fn_adaptor { + private: + typedef char one; + struct two { char v[2]; }; + private: + template + static T& get_ref(); + template + static one check_const(T&, Class*); + template + static one check_const(T&, Up* const*); + template + static two check_const(T&, Up const* const*); + template + static two check_const(T&, Class const*); + template + static two check_const(T&, const volatile void*); + public: + template + struct result_type + : public sprout::detail::mem_fn_const_or_non< + Res, + (sizeof(two) == sizeof(check_const(get_ref(), (T*)0))) + > + {}; + template + struct result; + template + struct result + : public result_type + {}; + template + struct result + : public result_type + {}; + private: + Res Class::* pm_; + private: + template + Res& call(T& object, Class*) const { + return object.*pm_; + } + template + Res& call(T& object, Up* const*) const { + return (*object).*pm_; + } + template + const Res& call(T& object, Up const* const*) const { + return (*object).*pm_; + } + template + Res const& call(T& object, Class const*) const { + return object.*pm_; + } + template + const Res& call(T& ptr, void const volatile*) const { + return (*ptr).*pm_; + } + public: + explicit SPROUT_CONSTEXPR mem_fn_adaptor(Res Class::* pm) + : pm_(pm) + {} + Res& operator()(Class& object) const { + return object.*pm_; + } + SPROUT_CONSTEXPR Res const& operator()(Class const& object) const { + return object.*pm_; + } + Res& operator()(Class* object) const { + return object->*pm_; + } + SPROUT_CONSTEXPR Res const& operator()(Class const* object) const { + return object->*pm_; + } + template + typename result_type::type operator()(T& unknown) const { + return call(unknown, &unknown); + } + }; + + // + // mem_fn + // + template + inline SPROUT_CONSTEXPR sprout::mem_fn_adaptor mem_fn(T Class::* pm) { + return sprout::mem_fn_adaptor(pm); + } +} // namespace sprout + +#endif // #ifndef SPROUT_FUNCTIONAL_MEM_FN_HPP diff --git a/sprout/functional/negator.hpp b/sprout/functional/negator.hpp new file mode 100644 index 00000000..b5bf4f60 --- /dev/null +++ b/sprout/functional/negator.hpp @@ -0,0 +1,8 @@ +#ifndef SPROUT_FUNCTIONAL_NEGATOR_HPP +#define SPROUT_FUNCTIONAL_NEGATOR_HPP + +#include +#include +#include + +#endif // #ifndef SPROUT_FUNCTIONAL_NEGATOR_HPP diff --git a/sprout/functional/not1.hpp b/sprout/functional/not1.hpp new file mode 100644 index 00000000..10948145 --- /dev/null +++ b/sprout/functional/not1.hpp @@ -0,0 +1,31 @@ +#ifndef SPROUT_FUNCTIONAL_NOT1_HPP +#define SPROUT_FUNCTIONAL_NOT1_HPP + +#include +#include + +namespace sprout { + // 20.8.8 negators + template + class unary_negate { + public: + typedef typename Predicate::argument_type argument_type; + typedef bool result_type; + protected: + Predicate fn; + public: + explicit SPROUT_CONSTEXPR unary_negate(Predicate const& pred) + : fn(pred) + {} + SPROUT_CONSTEXPR bool operator()(typename Predicate::argument_type const& x) const { + return !fn(x); + } + }; + + template + inline SPROUT_CONSTEXPR sprout::unary_negate not1(Predicate const& pred) { + return sprout::unary_negate(pred); + } +} // namespace sprout + +#endif // #ifndef SPROUT_FUNCTIONAL_NOT1_HPP diff --git a/sprout/functional/not2.hpp b/sprout/functional/not2.hpp new file mode 100644 index 00000000..f234d7ef --- /dev/null +++ b/sprout/functional/not2.hpp @@ -0,0 +1,32 @@ +#ifndef SPROUT_FUNCTIONAL_NOT2_HPP +#define SPROUT_FUNCTIONAL_NOT2_HPP + +#include +#include + +namespace sprout { + // 20.8.8 negators + template + class binary_negate { + public: + typedef typename Predicate::first_argument_type first_argument_type; + typedef typename Predicate::second_argument_type second_argument_type; + typedef bool result_type; + protected: + Predicate fn; + public: + explicit SPROUT_CONSTEXPR binary_negate(Predicate const& pred) + : fn(pred) + {} + SPROUT_CONSTEXPR bool operator()(typename Predicate::first_argument_type const& x, typename Predicate::second_argument_type const& y) const { + return !fn(x, y); + } + }; + + template + inline SPROUT_CONSTEXPR sprout::binary_negate not2(Predicate const& pred) { + return sprout::binary_negate(pred); + } +} // namespace sprout + +#endif // #ifndef SPROUT_FUNCTIONAL_NOT2_HPP diff --git a/sprout/functional/ref.hpp b/sprout/functional/ref.hpp new file mode 100644 index 00000000..8937fcfd --- /dev/null +++ b/sprout/functional/ref.hpp @@ -0,0 +1,262 @@ +#ifndef SPROUT_FUNCTIONAL_REF_HPP +#define SPROUT_FUNCTIONAL_REF_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + // 20.8.3 reference_wrapper + + namespace detail { + template + struct reference_wrapper_base_impl; + template + struct reference_wrapper_base_impl + : public sprout::weak_result_type + {}; + template + struct reference_wrapper_base_impl + : public sprout::weak_result_type + { + public: + typedef typename T::argument_type argument_type; + }; + template + struct reference_wrapper_base_impl + : public sprout::weak_result_type + { + public: + typedef typename T::first_argument_type first_argument_type; + typedef typename T::second_argument_type second_argument_type; + }; + template + struct reference_wrapper_base_impl + : public sprout::weak_result_type + { + public: + typedef typename T::argument_type argument_type; + typedef typename T::first_argument_type first_argument_type; + typedef typename T::second_argument_type second_argument_type; + }; + template + struct reference_wrapper_base + : public sprout::detail::reference_wrapper_base_impl< + sprout::detail::has_argument_type::value, + sprout::detail::has_first_argument_type::value + && sprout::detail::has_second_argument_type::value + , + T + > + {}; + template + struct reference_wrapper_base + : public sprout::unary_function + {}; + template + struct reference_wrapper_base + : public sprout::unary_function + {}; + template + struct reference_wrapper_base + : public sprout::unary_function + {}; + template + struct reference_wrapper_base + : public sprout::unary_function + {}; + template + struct reference_wrapper_base + : public sprout::binary_function + {}; + template + struct reference_wrapper_base + : public sprout::binary_function + {}; + template + struct reference_wrapper_base + : public sprout::binary_function + {}; + template + struct reference_wrapper_base + : public sprout::binary_function + {}; + template + struct reference_wrapper_base + : public sprout::unary_function + {}; + template + struct reference_wrapper_base + : public sprout::binary_function + {}; + template + struct reference_wrapper_base + : public sprout::unary_function + {}; + template + struct reference_wrapper_base + : public sprout::binary_function + {}; + template + struct reference_wrapper_base + : public sprout::unary_function + {}; + template + struct reference_wrapper_base + : public sprout::binary_function + {}; + template + struct reference_wrapper_base + : public sprout::unary_function + {}; + template + struct reference_wrapper_base + : public sprout::binary_function + {}; + template + struct reference_wrapper_base + : public sprout::unary_function + {}; + template + struct reference_wrapper_base + : public sprout::binary_function + {}; + } // namespace detail + + template + class reference_wrapper + : public sprout::detail::reference_wrapper_base::type> + { + public: + // types + typedef T type; + private: + T* t_; + public: + // construct/copy/destroy + SPROUT_CONSTEXPR reference_wrapper(T& t) SPROUT_NOEXCEPT + : t_(&t) + {} + reference_wrapper(T&&) = delete; + reference_wrapper(reference_wrapper const&) SPROUT_NOEXCEPT = default; + // assignment + reference_wrapper& operator=(reference_wrapper const&) SPROUT_NOEXCEPT = default; + // access + SPROUT_CONSTEXPR operator T& () const SPROUT_NOEXCEPT { + return *t_; + } + SPROUT_CONSTEXPR T& get() const SPROUT_NOEXCEPT { + return *t_; + } + SPROUT_CONSTEXPR T* get_pointer() const SPROUT_NOEXCEPT { + return t_; + } + // invocation + template + SPROUT_CONSTEXPR typename std::result_of::type + operator() (Args&&... args) const { + return (*t_)(sprout::forward(args)...); + } + }; + + // + // ref + // cref + // + template + inline SPROUT_CONSTEXPR sprout::reference_wrapper ref(T& t) SPROUT_NOEXCEPT { + return sprout::reference_wrapper(t); + } + template + inline SPROUT_CONSTEXPR sprout::reference_wrapper cref(T const& t) SPROUT_NOEXCEPT { + return sprout::reference_wrapper(t); + } + template + void ref(T const&&) = delete; + template + void cref(T const&&) = delete; + template + inline SPROUT_CONSTEXPR sprout::reference_wrapper ref(sprout::reference_wrapper t) SPROUT_NOEXCEPT { + return t; + } + template + inline SPROUT_CONSTEXPR sprout::reference_wrapper cref(sprout::reference_wrapper t) SPROUT_NOEXCEPT { + return sprout::reference_wrapper(t.get()); + } + + // + // is_reference_wrapper + // + template + struct is_reference_wrapper + : public std::false_type + {}; + template + struct is_reference_wrapper > + : public std::true_type + {}; + template + struct is_reference_wrapper + : public sprout::is_reference_wrapper + {}; + template + struct is_reference_wrapper + : public sprout::is_reference_wrapper + {}; + template + struct is_reference_wrapper + : public sprout::is_reference_wrapper + {}; + + // + // unwrap_reference + // + template + struct unwrap_reference { + public: + typedef T type; + }; + template + struct unwrap_reference > { + public: + typedef T type; + }; + template + struct unwrap_reference + : public sprout::unwrap_reference + {}; + template + struct unwrap_reference + : public sprout::unwrap_reference + {}; + template + struct unwrap_reference + : public sprout::unwrap_reference + {}; + + // + // unwrap_ref + // + template + inline typename sprout::unwrap_reference::type& unwrap_ref(T& t) { + return t; + } + template + inline SPROUT_CONSTEXPR typename sprout::unwrap_reference::type& unwrap_ref(T const& t) { + return t; + } + + // + // get_pointer + // + template + inline SPROUT_CONSTEXPR T* get_pointer(sprout::reference_wrapper const& r) { + return r.get_pointer(); + } +} // namespace sprout + +#endif // #ifndef SPROUT_FUNCTIONAL_REF_HPP diff --git a/sprout/functional/unary_function.hpp b/sprout/functional/unary_function.hpp new file mode 100644 index 00000000..56b9525b --- /dev/null +++ b/sprout/functional/unary_function.hpp @@ -0,0 +1,18 @@ +#ifndef SPROUT_FUNCTIONAL_UNARY_FUNCTION_HPP +#define SPROUT_FUNCTIONAL_UNARY_FUNCTION_HPP + +#include + +namespace sprout { + // + // unary_function + // + template + struct unary_function { + public: + typedef Arg argument_type; + typedef Result result_type; + }; +} // namespace sprout + +#endif // #ifndef SPROUT_FUNCTIONAL_UNARY_FUNCTION_HPP diff --git a/sprout/functional/weak_result_type.hpp b/sprout/functional/weak_result_type.hpp new file mode 100644 index 00000000..fb17b62a --- /dev/null +++ b/sprout/functional/weak_result_type.hpp @@ -0,0 +1,100 @@ +#ifndef SPROUT_FUNCTIONAL_WEAK_RESULT_TYPE_HPP +#define SPROUT_FUNCTIONAL_WEAK_RESULT_TYPE_HPP + +#include +#include +#include +#include + +namespace sprout { + namespace detail { + // + // has_result_type + // has_argument_type + // has_first_argument_type + // has_second_argument_type + // + SPROUT_HAS_XXX_TYPE_DEF_LAZY(result_type); + SPROUT_HAS_XXX_TYPE_DEF_LAZY(argument_type); + SPROUT_HAS_XXX_TYPE_DEF_LAZY(first_argument_type); + SPROUT_HAS_XXX_TYPE_DEF_LAZY(second_argument_type); + + // + // inherit_if_result_type + // inherit_if_argument_type + // inherit_if_first_argument_type + // inherit_if_second_argument_type + // + SPROUT_INHERIT_IF_XXX_TYPE_DEF_LAZY(result_type); + SPROUT_INHERIT_IF_XXX_TYPE_DEF_LAZY(argument_type); + SPROUT_INHERIT_IF_XXX_TYPE_DEF_LAZY(first_argument_type); + SPROUT_INHERIT_IF_XXX_TYPE_DEF_LAZY(second_argument_type); + + template + struct weak_result_type_impl + : public sprout::detail::inherit_if_result_type + {}; + template + struct weak_result_type_impl + : public sprout::detail::weak_result_type_impl + {}; + template + struct weak_result_type_impl + : public sprout::detail::weak_result_type_impl + {}; + template + struct weak_result_type_impl + : public sprout::detail::weak_result_type_impl + {}; + template + struct weak_result_type_impl { + public: + typedef R result_type; + }; + template + struct weak_result_type_impl { + public: + typedef R result_type; + }; + template + struct weak_result_type_impl { + public: + typedef R result_type; + }; + template + struct weak_result_type_impl { + public: + typedef R result_type; + }; + template + struct weak_result_type_impl { + public: + typedef R result_type; + }; + template + struct weak_result_type_impl { + public: + typedef R result_type; + }; + template + struct weak_result_type_impl { + public: + typedef R result_type; + }; + template + struct weak_result_type_impl { + public: + typedef R result_type; + }; + } // namespace detail + + // + // weak_result_type + // + template + struct weak_result_type + : public sprout::detail::weak_result_type_impl::type> + {}; +} // namespace sprout + +#endif // #ifndef SPROUT_FUNCTIONAL_WEAK_RESULT_TYPE_HPP diff --git a/sprout/tuple/tuple.hpp b/sprout/tuple/tuple.hpp index eea55232..6d643c7b 100644 --- a/sprout/tuple/tuple.hpp +++ b/sprout/tuple/tuple.hpp @@ -215,14 +215,9 @@ namespace sprout { : inherited_type(elements...) {} template - SPROUT_CONSTEXPR explicit tuple(UTypes const&... elements) - : inherited_type(elements...) + SPROUT_CONSTEXPR explicit tuple(UTypes&&... elements) + : inherited_type(sprout::forward(elements)...) {} - // !!! -// template -// SPROUT_CONSTEXPR explicit tuple(UTypes&&... elements) -// : inherited_type(sprout::forward(elements)...) -// {} SPROUT_CONSTEXPR tuple(tuple const&) = default; SPROUT_CONSTEXPR tuple(tuple&&) = default; template diff --git a/sprout/type_traits.hpp b/sprout/type_traits.hpp index 51df19f4..2349489f 100644 --- a/sprout/type_traits.hpp +++ b/sprout/type_traits.hpp @@ -4,5 +4,7 @@ #include #include #include +#include +#include #endif // #ifndef SPROUT_TYPE_TRAITS_HPP diff --git a/sprout/type_traits/has_xxx.hpp b/sprout/type_traits/has_xxx.hpp new file mode 100644 index 00000000..16460dcf --- /dev/null +++ b/sprout/type_traits/has_xxx.hpp @@ -0,0 +1,27 @@ +#ifndef SPROUT_TYPE_TRAITS_HAS_XXX_HPP +#define SPROUT_TYPE_TRAITS_HAS_XXX_HPP + +#include +#include +#include + +// +// SPROUT_HAS_XXX_TYPE_DEF +// +#define SPROUT_HAS_XXX_TYPE_DEF(NAME, TYPE) \ + template \ + std::true_type SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_has_xxx_impl_check_type_, TYPE), __LINE__)(int); \ + template \ + std::false_type SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_has_xxx_impl_check_type_, TYPE), __LINE__)(long); \ + template \ + struct NAME \ + : decltype(SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_has_xxx_impl_check_type_, TYPE), __LINE__)( 0 ) ) \ + {} + +// +// SPROUT_HAS_XXX_TYPE_DEF_LAZY +// +#define SPROUT_HAS_XXX_TYPE_DEF_LAZY(TYPE) \ + SPROUT_HAS_XXX_TYPE_DEF(SPROUT_PP_CAT(has_, TYPE), TYPE) + +#endif // #ifndef SPROUT_TYPE_TRAITS_HAS_XXX_HPP diff --git a/sprout/type_traits/inherit_if_xxx.hpp b/sprout/type_traits/inherit_if_xxx.hpp new file mode 100644 index 00000000..5d1fb20e --- /dev/null +++ b/sprout/type_traits/inherit_if_xxx.hpp @@ -0,0 +1,31 @@ +#ifndef SPROUT_TYPE_TRAITS_INHERIT_IF_XXX_HPP +#define SPROUT_TYPE_TRAITS_INHERIT_IF_XXX_HPP + +#include +#include +#include +#include + +// +// SPROUT_INHERIT_IF_XXX_TYPE_DEF +// +#define SPROUT_INHERIT_IF_XXX_TYPE_DEF(NAME, TYPE) \ + SPROUT_HAS_XXX_TYPE_DEF(SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_inherit_if_xxx_type_def_impl_has_, TYPE), __LINE__), TYPE); \ + template \ + struct NAME {}; \ + template \ + struct NAME< \ + T, \ + typename std::enable_if::value>::type \ + > { \ + public: \ + typedef typename T::TYPE TYPE; \ + } + +// +// SPROUT_INHERIT_IF_XXX_TYPE_DEF_LAZY +// +#define SPROUT_INHERIT_IF_XXX_TYPE_DEF_LAZY(TYPE) \ + SPROUT_INHERIT_IF_XXX_TYPE_DEF(SPROUT_PP_CAT(inherit_if_, TYPE), TYPE) + +#endif // #ifndef SPROUT_TYPE_TRAITS_INHERIT_IF_XXX_HPP