diff --git a/sprout/detail/one_type.hpp b/sprout/detail/one_type.hpp new file mode 100644 index 00000000..b286b5ac --- /dev/null +++ b/sprout/detail/one_type.hpp @@ -0,0 +1,30 @@ +/*============================================================================= + Copyright (c) 2011-2015 Bolero MURAKAMI + https://github.com/bolero-MURAKAMI/Sprout + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#ifndef SPROUT_DETAIL_ONE_TYPE_HPP +#define SPROUT_DETAIL_ONE_TYPE_HPP + +#include + +namespace sprout { + namespace detail { + // + // one_type + // + typedef char one_type; + + // + // not_one_type + // + struct not_one_type { + public: + char padding[8]; + }; + } // namespace detail +} // namespace sprout + +#endif // #ifndef SPROUT_DETAIL_ONE_TYPE_HPP diff --git a/sprout/type_traits/has_xxx.hpp b/sprout/type_traits/has_xxx.hpp index a7f7ac5d..e2cc9a11 100644 --- a/sprout/type_traits/has_xxx.hpp +++ b/sprout/type_traits/has_xxx.hpp @@ -8,12 +8,16 @@ #ifndef SPROUT_TYPE_TRAITS_HAS_XXX_HPP #define SPROUT_TYPE_TRAITS_HAS_XXX_HPP -#include +#include +#include #include #include #include #include +#define SPROUT_HAS_XXX_DETAIL_NAME_GEN(PREFIX, ELEM, NAME, NUM) \ + SPROUT_PP_CAT(SPROUT_PP_CAT(SPROUT_PP_CAT(PREFIX, ELEM), NAME), NUM) + // // SPROUT_HAS_XXX_TYPE_DEF // SPROUT_HAS_XXX_TYPE_DEF_LAZY @@ -21,22 +25,22 @@ #if defined(_MSC_VER) && (_MSC_VER > 1900) #define SPROUT_HAS_XXX_TYPE_DEF_IMPL(NAME, TYPE, NUM) \ template \ - sprout::true_type SPROUT_PP_CAT(SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_has_xxx_impl_check_type_, TYPE), NAME), NUM)(int); \ + sprout::true_type SPROUT_HAS_XXX_DETAIL_NAME_GEN(sprout_has_xxx_impl_check_type_, TYPE, NAME, NUM)(int); \ template \ - sprout::false_type SPROUT_PP_CAT(SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_has_xxx_impl_check_type_, TYPE), NAME), NUM)(long); \ - template(0))> \ + sprout::false_type SPROUT_HAS_XXX_DETAIL_NAME_GEN(sprout_has_xxx_impl_check_type_, TYPE, NAME, NUM)(long); \ + template(0))> \ struct NAME \ : public Base_ \ {} #else #define SPROUT_HAS_XXX_TYPE_DEF_IMPL(NAME, TYPE, NUM) \ template \ - sprout::true_type SPROUT_PP_CAT(SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_has_xxx_impl_check_type_, TYPE), NAME), NUM)(int); \ + sprout::true_type SPROUT_HAS_XXX_DETAIL_NAME_GEN(sprout_has_xxx_impl_check_type_, TYPE, NAME, NUM)(int); \ template \ - sprout::false_type SPROUT_PP_CAT(SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_has_xxx_impl_check_type_, TYPE), NAME), NUM)(long); \ + sprout::false_type SPROUT_HAS_XXX_DETAIL_NAME_GEN(sprout_has_xxx_impl_check_type_, TYPE, NAME, NUM)(long); \ template \ struct NAME \ - : public sprout::identity(0))>::type \ + : public sprout::identity(0))>::type \ {} #endif #define SPROUT_HAS_XXX_TYPE_DEF(NAME, TYPE) \ @@ -48,25 +52,50 @@ // SPROUT_HAS_XXX_VALUE_DEF // SPROUT_HAS_XXX_VALUE_DEF_LAZY // -#if defined(_MSC_VER) && (_MSC_VER > 1900) -#define SPROUT_HAS_XXX_VALUE_DEF_IMPL(NAME, VALUE, NUM) \ - template::type = &T::VALUE> \ - sprout::true_type SPROUT_PP_CAT(SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_has_xxx_impl_check_value_, VALUE), NAME), NUM)(int); \ +#if defined(_MSC_VER) +#define SPROUT_HAS_XXX_VALUE_DEF_IMPL_HSD_OP(NAME, VALUE, NUM) \ + template \ + struct SPROUT_HAS_XXX_DETAIL_NAME_GEN(sprout_has_xxx_impl_check_value_hsd_op_, VALUE, NAME, NUM) { \ + private: \ + template \ + static sprout::detail::one_type check2(V*); \ + template \ + static sprout::detail::not_one_type check2(U); \ + private: \ + template \ + static typename std::enable_if< \ + sizeof(check2(&U::VALUE)) == sizeof(sprout::detail::one_type), \ + sprout::detail::one_type \ + >::type has_matching_member(int); \ + template \ + static sprout::detail::not_one_type has_matching_member(...); \ + private: \ + template \ + struct ttc_sd \ + : public sprout::bool_constant(0)) == sizeof(sprout::detail::one_type)> \ + {}; \ + public: \ + typedef typename ttc_sd::type type; \ + } +#define SPROUT_HAS_XXX_VALUE_DEF_IMPL(NAME, VALUE, NUM) \ + SPROUT_HAS_XXX_VALUE_DEF_IMPL_HSD_OP(NAME, VALUE, NUM); \ template \ - sprout::false_type SPROUT_PP_CAT(SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_has_xxx_impl_check_value_, VALUE), NAME), NUM)(long); \ - template(0))> \ struct NAME \ - : public Base_ \ + : public std::conditional< \ + std::is_class::value, \ + SPROUT_HAS_XXX_DETAIL_NAME_GEN(sprout_has_xxx_impl_check_value_hsd_op_, VALUE, NAME, NUM), \ + sprout::false_type \ + >::type::type \ {} #else #define SPROUT_HAS_XXX_VALUE_DEF_IMPL(NAME, VALUE, NUM) \ template::type = &T::VALUE> \ - sprout::true_type SPROUT_PP_CAT(SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_has_xxx_impl_check_value_, VALUE), NAME), NUM)(int); \ + sprout::true_type SPROUT_HAS_XXX_DETAIL_NAME_GEN(sprout_has_xxx_impl_check_value_, VALUE, NAME, NUM)(int); \ template \ - sprout::false_type SPROUT_PP_CAT(SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_has_xxx_impl_check_value_, VALUE), NAME), NUM)(long); \ + sprout::false_type SPROUT_HAS_XXX_DETAIL_NAME_GEN(sprout_has_xxx_impl_check_value_, VALUE, NAME, NUM)(long); \ template \ struct NAME \ - : public sprout::identity(0))>::type \ + : public sprout::identity(0))>::type \ {} #endif #define SPROUT_HAS_XXX_VALUE_DEF(NAME, VALUE) \ @@ -81,22 +110,22 @@ #if defined(_MSC_VER) && (_MSC_VER > 1900) #define SPROUT_HAS_XXX_TEMPLATE_DEF_IMPL(NAME, TEMPLATE, NUM) \ template class = T::template TEMPLATE> \ - sprout::true_type SPROUT_PP_CAT(SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_has_xxx_impl_check_type_, TEMPLATE), NAME), NUM)(int); \ + sprout::true_type SPROUT_HAS_XXX_DETAIL_NAME_GEN(sprout_has_xxx_impl_check_type_, TEMPLATE, NAME, NUM)(int); \ template \ - sprout::false_type SPROUT_PP_CAT(SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_has_xxx_impl_check_type_, TEMPLATE), NAME), NUM)(long); \ - template(0))> \ + sprout::false_type SPROUT_HAS_XXX_DETAIL_NAME_GEN(sprout_has_xxx_impl_check_type_, TEMPLATE, NAME, NUM)(long); \ + template(0))> \ struct NAME \ : public Base_ \ {} #else #define SPROUT_HAS_XXX_TEMPLATE_DEF_IMPL(NAME, TEMPLATE, NUM) \ template class = T::template TEMPLATE> \ - sprout::true_type SPROUT_PP_CAT(SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_has_xxx_impl_check_type_, TEMPLATE), NAME), NUM)(int); \ + sprout::true_type SPROUT_HAS_XXX_DETAIL_NAME_GEN(sprout_has_xxx_impl_check_type_, TEMPLATE, NAME, NUM)(int); \ template \ - sprout::false_type SPROUT_PP_CAT(SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_has_xxx_impl_check_type_, TEMPLATE), NAME), NUM)(long); \ + sprout::false_type SPROUT_HAS_XXX_DETAIL_NAME_GEN(sprout_has_xxx_impl_check_type_, TEMPLATE, NAME, NUM)(long); \ template \ struct NAME \ - : public sprout::identity(0))>::type \ + : public sprout::identity(0))>::type \ {} #endif #define SPROUT_HAS_XXX_TEMPLATE_DEF(NAME, TEMPLATE) \ diff --git a/sprout/type_traits/integral_constant.hpp b/sprout/type_traits/integral_constant.hpp index 47d45388..23ddf618 100644 --- a/sprout/type_traits/integral_constant.hpp +++ b/sprout/type_traits/integral_constant.hpp @@ -23,6 +23,8 @@ namespace sprout { typedef typename std::integral_constant::value_type value_type; typedef integral_constant type; public: + SPROUT_STATIC_CONSTEXPR value_type value = V; + public: #if defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC) SPROUT_CONSTEXPR integral_constant() SPROUT_NOEXCEPT {} integral_constant(integral_constant const&) = default; @@ -40,6 +42,8 @@ namespace sprout { return std::integral_constant::value; } }; + template + SPROUT_CONSTEXPR_OR_CONST typename sprout::integral_constant::value_type sprout::integral_constant::value; // // bool_constant