fix for VC++11

This commit is contained in:
bolero-MURAKAMI 2012-12-17 20:10:17 +09:00
parent d5c61e65ca
commit f673db1451
18 changed files with 382 additions and 164 deletions

View file

@ -8,7 +8,6 @@
#include <sprout/index_tuple.hpp> #include <sprout/index_tuple.hpp>
#include <sprout/pit.hpp> #include <sprout/pit.hpp>
#include <sprout/iterator/type_traits/is_iterator.hpp> #include <sprout/iterator/type_traits/is_iterator.hpp>
#include <sprout/type_traits/enabler_if.hpp>
#include <sprout/range/adaptor/size_enumed.hpp> #include <sprout/range/adaptor/size_enumed.hpp>
#include <sprout/range/algorithm/lower_bound.hpp> #include <sprout/range/algorithm/lower_bound.hpp>
#include <sprout/range/numeric/partial_sum.hpp> #include <sprout/range/numeric/partial_sum.hpp>
@ -40,19 +39,19 @@ namespace sprout {
> >
{}; {};
template< template<typename String>
typename String, inline SPROUT_CONSTEXPR typename std::enable_if<
typename sprout::enabler_if<sprout::is_c_str<String>::value>::type = sprout::enabler sprout::is_c_str<String>::value,
> typename sprout::container_traits<String>::difference_type
inline SPROUT_CONSTEXPR typename sprout::container_traits<String>::difference_type >::type
str_size(String const& str) { str_size(String const& str) {
return sprout::size(str) - 1; return sprout::size(str) - 1;
} }
template< template<typename String>
typename String, inline SPROUT_CONSTEXPR typename std::enable_if<
typename sprout::enabler_if<!sprout::is_c_str<String>::value>::type = sprout::enabler !sprout::is_c_str<String>::value,
> typename sprout::container_traits<String>::difference_type
inline SPROUT_CONSTEXPR typename sprout::container_traits<String>::difference_type >::type
str_size(String const& str) { str_size(String const& str) {
return sprout::size(str); return sprout::size(str);
} }
@ -230,9 +229,8 @@ namespace sprout {
; ;
} }
template< template<typename ContainerContainer>
typename ContainerContainer, inline SPROUT_CONSTEXPR typename std::enable_if<
typename sprout::enabler_if<
sprout::is_random_access_iterator< sprout::is_random_access_iterator<
typename sprout::container_traits<ContainerContainer const>::iterator typename sprout::container_traits<ContainerContainer const>::iterator
>::value >::value
@ -241,16 +239,15 @@ namespace sprout {
typename sprout::container_traits<ContainerContainer const>::value_type typename sprout::container_traits<ContainerContainer const>::value_type
>::iterator >::iterator
>::value >::value
>::type = sprout::enabler ,
> typename sprout::algorithm::result_of::join<ContainerContainer>::type
inline SPROUT_CONSTEXPR typename sprout::algorithm::result_of::join<ContainerContainer>::type >::type
join(ContainerContainer const& cont_cont) { join(ContainerContainer const& cont_cont) {
typedef typename sprout::algorithm::result_of::join<ContainerContainer>::type result_type; typedef typename sprout::algorithm::result_of::join<ContainerContainer>::type result_type;
return sprout::algorithm::detail::join_impl_ra<result_type>(cont_cont); return sprout::algorithm::detail::join_impl_ra<result_type>(cont_cont);
} }
template< template<typename ContainerContainer>
typename ContainerContainer, inline SPROUT_CONSTEXPR typename std::enable_if<!(
typename sprout::enabler_if<!(
sprout::is_random_access_iterator< sprout::is_random_access_iterator<
typename sprout::container_traits<ContainerContainer const>::iterator typename sprout::container_traits<ContainerContainer const>::iterator
>::value >::value
@ -259,9 +256,9 @@ namespace sprout {
typename sprout::container_traits<ContainerContainer const>::value_type typename sprout::container_traits<ContainerContainer const>::value_type
>::iterator >::iterator
>::value >::value
)>::type = sprout::enabler ),
> typename sprout::algorithm::result_of::join<ContainerContainer>::type
inline SPROUT_CONSTEXPR typename sprout::algorithm::result_of::join<ContainerContainer>::type >::type
join(ContainerContainer const& cont_cont) { join(ContainerContainer const& cont_cont) {
typedef typename sprout::algorithm::result_of::join<ContainerContainer>::type result_type; typedef typename sprout::algorithm::result_of::join<ContainerContainer>::type result_type;
return sprout::algorithm::detail::join_impl<result_type>( return sprout::algorithm::detail::join_impl<result_type>(
@ -457,10 +454,8 @@ namespace sprout {
; ;
} }
template< template<typename ContainerContainer, typename Separator>
typename ContainerContainer, inline SPROUT_CONSTEXPR typename std::enable_if<
typename Separator,
typename sprout::enabler_if<
sprout::is_random_access_iterator< sprout::is_random_access_iterator<
typename sprout::container_traits<ContainerContainer const>::iterator typename sprout::container_traits<ContainerContainer const>::iterator
>::value >::value
@ -472,17 +467,15 @@ namespace sprout {
&& sprout::is_random_access_iterator< && sprout::is_random_access_iterator<
typename sprout::container_traits<Separator const>::iterator typename sprout::container_traits<Separator const>::iterator
>::value >::value
>::type = sprout::enabler ,
> typename sprout::algorithm::result_of::join<ContainerContainer, Separator>::type
inline SPROUT_CONSTEXPR typename sprout::algorithm::result_of::join<ContainerContainer>::type >::type
join(ContainerContainer const& cont_cont, Separator const& separator) { join(ContainerContainer const& cont_cont, Separator const& separator) {
typedef typename sprout::algorithm::result_of::join<ContainerContainer>::type result_type; typedef typename sprout::algorithm::result_of::join<ContainerContainer, Separator>::type result_type;
return sprout::algorithm::detail::join_impl_ra<result_type>(cont_cont, separator); return sprout::algorithm::detail::join_impl_ra<result_type>(cont_cont, separator);
} }
template< template<typename ContainerContainer, typename Separator>
typename ContainerContainer, inline SPROUT_CONSTEXPR typename std::enable_if<!(
typename Separator,
typename sprout::enabler_if<!(
sprout::is_random_access_iterator< sprout::is_random_access_iterator<
typename sprout::container_traits<ContainerContainer const>::iterator typename sprout::container_traits<ContainerContainer const>::iterator
>::value >::value
@ -494,11 +487,11 @@ namespace sprout {
&& sprout::is_random_access_iterator< && sprout::is_random_access_iterator<
typename sprout::container_traits<Separator const>::iterator typename sprout::container_traits<Separator const>::iterator
>::value >::value
)>::type = sprout::enabler ),
> typename sprout::algorithm::result_of::join<ContainerContainer, Separator>::type
inline SPROUT_CONSTEXPR typename sprout::algorithm::result_of::join<ContainerContainer>::type >::type
join(ContainerContainer const& cont_cont, Separator const& separator) { join(ContainerContainer const& cont_cont, Separator const& separator) {
typedef typename sprout::algorithm::result_of::join<ContainerContainer>::type result_type; typedef typename sprout::algorithm::result_of::join<ContainerContainer, Separator>::type result_type;
return sprout::algorithm::detail::join_impl<result_type>( return sprout::algorithm::detail::join_impl<result_type>(
sprout::begin(cont_cont), sprout::begin(cont_cont),
sprout::end(cont_cont), sprout::end(cont_cont),

View file

@ -28,13 +28,19 @@ namespace sprout {
: 1 + sprout::detail::clz_impl(n, static_cast<T>(m >> 1)) : 1 + sprout::detail::clz_impl(n, static_cast<T>(m >> 1))
; ;
} }
template<typename T, typename sprout::enabler_if<std::is_unsigned<T>::value>::type = sprout::enabler> template<typename T>
inline SPROUT_CONSTEXPR int inline SPROUT_CONSTEXPR typename std::enable_if<
std::is_unsigned<T>::value,
int
>::type
clz(T n) { clz(T n) {
return sprout::detail::clz_impl(static_cast<T>(n)); return sprout::detail::clz_impl(static_cast<T>(n));
} }
template<typename T, typename sprout::enabler_if<std::is_signed<T>::value>::type = sprout::enabler> template<typename T>
inline SPROUT_CONSTEXPR int inline SPROUT_CONSTEXPR typename std::enable_if<
std::is_signed<T>::value,
int
>::type
clz(T n) { clz(T n) {
return sprout::detail::clz(static_cast<typename std::make_unsigned<T>::type>(n)); return sprout::detail::clz(static_cast<typename std::make_unsigned<T>::type>(n));
} }
@ -42,8 +48,11 @@ namespace sprout {
// //
// clz // clz
// //
template<typename T, typename sprout::enabler_if<std::is_integral<T>::value>::type = sprout::enabler> template<typename T>
inline SPROUT_CONSTEXPR int inline SPROUT_CONSTEXPR typename std::enable_if<
std::is_integral<T>::value,
int
>::type
clz(T n) { clz(T n) {
return sprout::detail::clz(n); return sprout::detail::clz(n);
} }

View file

@ -20,15 +20,21 @@ namespace sprout {
return __builtin_ctzll(n); return __builtin_ctzll(n);
} }
# endif # endif
template<typename T, typename sprout::enabler_if<std::is_unsigned<T>::value>::type = sprout::enabler> template<typename T>
inline SPROUT_CONSTEXPR int inline SPROUT_CONSTEXPR typename std::enable_if<
std::is_unsigned<T>::value,
int
>::type
ctz(T n) { ctz(T n) {
return n & 1 ? 0 return n & 1 ? 0
: 1 + sprout::detail::ctz(static_cast<T>(n >> 1)) : 1 + sprout::detail::ctz(static_cast<T>(n >> 1))
; ;
} }
template<typename T, typename sprout::enabler_if<std::is_signed<T>::value>::type = sprout::enabler> template<typename T>
inline SPROUT_CONSTEXPR int inline SPROUT_CONSTEXPR typename std::enable_if<
std::is_signed<T>::value,
int
>::type
ctz(T n) { ctz(T n) {
return sprout::detail::ctz(static_cast<typename std::make_unsigned<T>::type>(n)); return sprout::detail::ctz(static_cast<typename std::make_unsigned<T>::type>(n));
} }
@ -36,8 +42,11 @@ namespace sprout {
// //
// ctz // ctz
// //
template<typename T, typename sprout::enabler_if<std::is_integral<T>::value>::type = sprout::enabler> template<typename T>
inline SPROUT_CONSTEXPR int inline SPROUT_CONSTEXPR typename std::enable_if<
std::is_integral<T>::value,
int
>::type
ctz(T n) { ctz(T n) {
return sprout::detail::ctz(n); return sprout::detail::ctz(n);
} }

View file

@ -3,7 +3,6 @@
#include <type_traits> #include <type_traits>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/type_traits/enabler_if.hpp>
namespace sprout { namespace sprout {
namespace detail { namespace detail {
@ -21,15 +20,21 @@ namespace sprout {
return __builtin_popcountll(n); return __builtin_popcountll(n);
} }
# endif # endif
template<typename T, typename sprout::enabler_if<std::is_unsigned<T>::value>::type = sprout::enabler> template<typename T>
inline SPROUT_CONSTEXPR int inline SPROUT_CONSTEXPR typename std::enable_if<
std::is_unsigned<T>::value,
int
>::type
popcount(T n) { popcount(T n) {
return n == 0 ? 0 return n == 0 ? 0
: 1 + sprout::detail::popcount(static_cast<T>(n & (n - 1))) : 1 + sprout::detail::popcount(static_cast<T>(n & (n - 1)))
; ;
} }
template<typename T, typename sprout::enabler_if<std::is_signed<T>::value>::type = sprout::enabler> template<typename T>
inline SPROUT_CONSTEXPR int inline SPROUT_CONSTEXPR typename std::enable_if<
std::is_signed<T>::value,
int
>::type
popcount(T n) { popcount(T n) {
return sprout::detail::popcount(static_cast<typename std::make_unsigned<T>::type>(n)); return sprout::detail::popcount(static_cast<typename std::make_unsigned<T>::type>(n));
} }
@ -37,8 +42,11 @@ namespace sprout {
// //
// popcount // popcount
// //
template<typename T, typename sprout::enabler_if<std::is_integral<T>::value>::type = sprout::enabler> template<typename T>
inline SPROUT_CONSTEXPR int inline SPROUT_CONSTEXPR typename std::enable_if<
std::is_integral<T>::value,
int
>::type
popcount(T n) { popcount(T n) {
return sprout::detail::popcount(n); return sprout::detail::popcount(n);
} }

View file

@ -5,14 +5,16 @@
#include <climits> #include <climits>
#include <type_traits> #include <type_traits>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/type_traits/enabler_if.hpp>
namespace sprout { namespace sprout {
// //
// left_rotate // left_rotate
// //
template<typename T, typename sprout::enabler_if<std::is_integral<T>::value>::type = sprout::enabler> template<typename T>
inline SPROUT_CONSTEXPR T inline SPROUT_CONSTEXPR typename std::enable_if<
std::is_integral<T>::value,
T
>::type
left_rotate(T x, std::size_t n) { left_rotate(T x, std::size_t n) {
return (x << n) ^ (x >> (sizeof(T) * CHAR_BIT - n)); return (x << n) ^ (x >> (sizeof(T) * CHAR_BIT - n));
} }
@ -20,8 +22,11 @@ namespace sprout {
// //
// right_rotate // right_rotate
// //
template<typename T, typename sprout::enabler_if<std::is_integral<T>::value>::type = sprout::enabler> template<typename T>
inline SPROUT_CONSTEXPR T inline SPROUT_CONSTEXPR typename std::enable_if<
std::is_integral<T>::value,
T
>::type
right_rotate(T x, std::size_t n) { right_rotate(T x, std::size_t n) {
return (x >> n) ^ (x << (sizeof(T) * CHAR_BIT - n)); return (x >> n) ^ (x << (sizeof(T) * CHAR_BIT - n));
} }

View file

@ -2,9 +2,7 @@
#define SPROUT_CINTTYPES_ABS_HPP #define SPROUT_CINTTYPES_ABS_HPP
#include <cstdint> #include <cstdint>
#include <type_traits>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/type_traits/enabler_if.hpp>
namespace sprout { namespace sprout {
inline SPROUT_CONSTEXPR std::intmax_t inline SPROUT_CONSTEXPR std::intmax_t

View file

@ -4,12 +4,26 @@
#include <cstddef> #include <cstddef>
#include <cstdlib> #include <cstdlib>
#include <cstdint> #include <cstdint>
#if !defined(_MSC_VER)
# include <cinttypes> # include <cinttypes>
#endif
#include <type_traits> #include <type_traits>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/type_traits/enabler_if.hpp>
namespace sprout { namespace sprout {
//
// imaxdiv_t
//
#if defined(_MSC_VER)
struct imaxdiv_t {
public:
std::intmax_t quot;
std::intmax_t rem;
};
#else
typedef std::imaxdiv_t imaxdiv_t;
#endif
namespace detail { namespace detail {
template<typename T> template<typename T>
struct div_t_traits2 {}; struct div_t_traits2 {};
@ -23,42 +37,48 @@ namespace sprout {
SPROUT_STATIC_CONSTEXPR std::size_t offsetof_rem = offsetof(DIV_T, rem); \ SPROUT_STATIC_CONSTEXPR std::size_t offsetof_rem = offsetof(DIV_T, rem); \
} }
SPROUT_DETAIL_DIV_T_TRAITS2_IMPL(std::intmax_t, std::imaxdiv_t); SPROUT_DETAIL_DIV_T_TRAITS2_IMPL(std::intmax_t, sprout::imaxdiv_t);
# undef SPROUT_DETAIL_DIV_T_TRAITS2_IMPL # undef SPROUT_DETAIL_DIV_T_TRAITS2_IMPL
template< template<typename T>
typename T, inline SPROUT_CONSTEXPR typename std::enable_if<
typename sprout::enabler_if< sprout::detail::div_t_traits2<T>::offsetof_quot == 0,
sprout::detail::div_t_traits2<T>::offsetof_quot == 0 typename sprout::detail::div_t_traits2<T>::type
>::type = sprout::enabler >::type
>
inline SPROUT_CONSTEXPR typename sprout::detail::div_t_traits2<T>::type
div_impl2(T const& numer, T const& denom) { div_impl2(T const& numer, T const& denom) {
#if defined(_MSC_VER)
typename sprout::detail::div_t_traits2<T>::type result = {numer / denom, numer % denom};
return result;
#else
return {numer / denom, numer % denom}; return {numer / denom, numer % denom};
#endif
} }
template< template<typename T>
typename T, inline SPROUT_CONSTEXPR typename std::enable_if<
typename sprout::enabler_if< sprout::detail::div_t_traits2<T>::offsetof_rem == 0,
sprout::detail::div_t_traits2<T>::offsetof_rem == 0 typename sprout::detail::div_t_traits2<T>::type
>::type = sprout::enabler >::type
>
inline SPROUT_CONSTEXPR typename sprout::detail::div_t_traits2<T>::type
div_impl2(T const &numer, T const& denom) { div_impl2(T const &numer, T const& denom) {
#if defined(_MSC_VER)
typename sprout::detail::div_t_traits2<T>::type result = {numer % denom, numer / denom};
return result;
#else
return {numer % denom, numer / denom}; return {numer % denom, numer / denom};
#endif
} }
} // namespace detail } // namespace detail
inline SPROUT_CONSTEXPR std::imaxdiv_t inline SPROUT_CONSTEXPR sprout::imaxdiv_t
imaxdiv(std::intmax_t numer, std::intmax_t denom) { imaxdiv(std::intmax_t numer, std::intmax_t denom) {
return sprout::detail::div_impl2(numer, denom); return sprout::detail::div_impl2(numer, denom);
} }
template< template<typename T>
typename T, inline SPROUT_CONSTEXPR typename std::enable_if<
typename sprout::enabler_if<std::is_same<T, std::intmax_t>::value>::type = sprout::enabler std::is_same<T, std::intmax_t>::value,
> sprout::imaxdiv_t
inline SPROUT_CONSTEXPR std::imaxdiv_t >::type
div(T numer, T denom) { div(T numer, T denom) {
return sprout::imaxdiv(numer, denom); return sprout::imaxdiv(numer, denom);
} }

View file

@ -15,10 +15,17 @@ namespace sprout {
std::true_type sprout_has_xxx_impl_check_template_rebind_size(int); std::true_type sprout_has_xxx_impl_check_template_rebind_size(int);
template<typename T> template<typename T>
std::false_type sprout_has_xxx_impl_check_template_rebind_size(long); std::false_type sprout_has_xxx_impl_check_template_rebind_size(long);
#if defined(_MSC_VER)
template<typename T, typename Base_ = decltype(sprout::containers::detail::sprout_has_xxx_impl_check_template_rebind_size<T>(0))>
struct has_rebind_size
: public Base_
{};
#else
template<typename T> template<typename T>
struct has_rebind_size struct has_rebind_size
: decltype(sprout::containers::detail::sprout_has_xxx_impl_check_template_rebind_size<T>(0)) : public decltype(sprout::containers::detail::sprout_has_xxx_impl_check_template_rebind_size<T>(0))
{}; {};
#endif
} // namespace detail } // namespace detail
// //
// is_rebindable_size // is_rebindable_size

View file

@ -3,7 +3,6 @@
#include <type_traits> #include <type_traits>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/type_traits/enabler_if.hpp>
namespace sprout { namespace sprout {
// Copyright (C) 2011 RiSK (sscrisk) // Copyright (C) 2011 RiSK (sscrisk)
@ -35,23 +34,20 @@ namespace sprout {
} }
namespace { namespace {
template< template<typename IntType>
typename IntType, inline SPROUT_CONSTEXPR typename std::enable_if<
typename sprout::enabler_if< std::is_integral<IntType>::value && std::is_signed<IntType>::value,
std::is_integral<IntType>::value && std::is_signed<IntType>::value IntType
>::type = sprout::enabler >::type
>
inline SPROUT_CONSTEXPR IntType
abs(IntType j) { abs(IntType j) {
return j < 0 ? -j : j; return j < 0 ? -j : j;
} }
template<
typename IntType, template<typename IntType>
typename sprout::enabler_if< inline SPROUT_CONSTEXPR typename std::enable_if<
std::is_integral<IntType>::value && std::is_unsigned<IntType>::value std::is_integral<IntType>::value && std::is_unsigned<IntType>::value,
>::type = sprout::enabler IntType
> >::type
inline SPROUT_CONSTEXPR IntType
abs(IntType j) { abs(IntType j) {
return j; return j;
} }

View file

@ -7,7 +7,6 @@
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/iterator/operation.hpp> #include <sprout/iterator/operation.hpp>
#include <sprout/ctype/ascii.hpp> #include <sprout/ctype/ascii.hpp>
#include <sprout/type_traits/enabler_if.hpp>
namespace sprout { namespace sprout {
namespace detail { namespace detail {
@ -27,8 +26,11 @@ namespace sprout {
) )
; ;
} }
template<typename IntType, typename CStrIterator, typename sprout::enabler_if<std::is_unsigned<IntType>::value>::type = sprout::enabler> template<typename IntType, typename CStrIterator>
inline SPROUT_CONSTEXPR IntType inline SPROUT_CONSTEXPR typename std::enable_if<
std::is_unsigned<IntType>::value,
IntType
>::type
ascii_to_int(CStrIterator str) { ascii_to_int(CStrIterator str) {
return sprout::ascii::isspace(*str) return sprout::ascii::isspace(*str)
? sprout::detail::ascii_to_int<IntType>(sprout::next(str)) ? sprout::detail::ascii_to_int<IntType>(sprout::next(str))
@ -37,8 +39,11 @@ namespace sprout {
: sprout::detail::ascii_to_int_impl<IntType>(str, IntType(), false) : sprout::detail::ascii_to_int_impl<IntType>(str, IntType(), false)
; ;
} }
template<typename IntType, typename CStrIterator, typename sprout::enabler_if<std::is_signed<IntType>::value>::type = sprout::enabler> template<typename IntType, typename CStrIterator>
inline SPROUT_CONSTEXPR IntType inline SPROUT_CONSTEXPR typename std::enable_if<
std::is_signed<IntType>::value,
IntType
>::type
ascii_to_int(CStrIterator str) { ascii_to_int(CStrIterator str) {
return sprout::ascii::isspace(*str) return sprout::ascii::isspace(*str)
? sprout::detail::ascii_to_int<IntType>(sprout::next(str)) ? sprout::detail::ascii_to_int<IntType>(sprout::next(str))
@ -54,8 +59,11 @@ namespace sprout {
// //
// ascii_to_int // ascii_to_int
// //
template<typename IntType, typename Char, typename sprout::enabler_if<std::is_integral<IntType>::value>::type = sprout::enabler> template<typename IntType, typename Char>
inline SPROUT_CONSTEXPR IntType inline SPROUT_CONSTEXPR typename std::enable_if<
std::is_integral<IntType>::value,
IntType
>::type
ascii_to_int(Char const* str) { ascii_to_int(Char const* str) {
return sprout::detail::ascii_to_int<IntType>(str); return sprout::detail::ascii_to_int<IntType>(str);
} }

View file

@ -5,7 +5,6 @@
#include <cstdlib> #include <cstdlib>
#include <type_traits> #include <type_traits>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/type_traits/enabler_if.hpp>
namespace sprout { namespace sprout {
// Copyright (C) 2011 RiSK (sscrisk) // Copyright (C) 2011 RiSK (sscrisk)
@ -28,26 +27,32 @@ namespace sprout {
SPROUT_DETAIL_DIV_T_TRAITS_IMPL(long long, std::lldiv_t); SPROUT_DETAIL_DIV_T_TRAITS_IMPL(long long, std::lldiv_t);
# undef SPROUT_DETAIL_DIV_T_TRAITS_IMPL # undef SPROUT_DETAIL_DIV_T_TRAITS_IMPL
template< template<typename T>
typename T, inline SPROUT_CONSTEXPR typename std::enable_if<
typename sprout::enabler_if< sprout::detail::div_t_traits<T>::offsetof_quot == 0,
sprout::detail::div_t_traits<T>::offsetof_quot == 0 typename sprout::detail::div_t_traits<T>::type
>::type = sprout::enabler >::type
>
inline SPROUT_CONSTEXPR typename sprout::detail::div_t_traits<T>::type
div_impl(T const& numer, T const& denom) { div_impl(T const& numer, T const& denom) {
#if defined(_MSC_VER)
typename sprout::detail::div_t_traits<T>::type result = {numer / denom, numer % denom};
return result;
#else
return {numer / denom, numer % denom}; return {numer / denom, numer % denom};
#endif
} }
template< template<typename T>
typename T, inline SPROUT_CONSTEXPR typename std::enable_if<
typename sprout::enabler_if< sprout::detail::div_t_traits<T>::offsetof_rem == 0,
sprout::detail::div_t_traits<T>::offsetof_rem == 0 typename sprout::detail::div_t_traits<T>::type
>::type = sprout::enabler >::type
>
inline SPROUT_CONSTEXPR typename sprout::detail::div_t_traits<T>::type
div_impl(T const &numer, T const& denom) { div_impl(T const &numer, T const& denom) {
#if defined(_MSC_VER)
typename sprout::detail::div_t_traits<T>::type result = {numer % denom, numer / denom};
return result;
#else
return {numer % denom, numer / denom}; return {numer % denom, numer / denom};
#endif
} }
} // namespace detail } // namespace detail

View file

@ -8,7 +8,6 @@
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/iterator/operation.hpp> #include <sprout/iterator/operation.hpp>
#include <sprout/ctype/ascii.hpp> #include <sprout/ctype/ascii.hpp>
#include <sprout/type_traits/enabler_if.hpp>
namespace sprout { namespace sprout {
namespace detail { namespace detail {
@ -246,18 +245,29 @@ namespace sprout {
// //
// str_to_float // str_to_float
// //
template<typename FloatType, typename Char, typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler> template<typename FloatType, typename Char>
inline SPROUT_CONSTEXPR FloatType inline SPROUT_CONSTEXPR typename std::enable_if<
std::is_floating_point<FloatType>::value,
FloatType
>::type
str_to_float(Char const* str, Char** endptr) { str_to_float(Char const* str, Char** endptr) {
return sprout::detail::str_to_float<FloatType>(str, endptr); return sprout::detail::str_to_float<FloatType>(str, endptr);
} }
template<typename FloatType, typename Char, typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler>
inline SPROUT_CONSTEXPR FloatType template<typename FloatType, typename Char>
inline SPROUT_CONSTEXPR typename std::enable_if<
std::is_floating_point<FloatType>::value,
FloatType
>::type
str_to_float(Char const* str, std::nullptr_t endptr) { str_to_float(Char const* str, std::nullptr_t endptr) {
return sprout::detail::str_to_float<FloatType>(str); return sprout::detail::str_to_float<FloatType>(str);
} }
template<typename FloatType, typename Char, typename sprout::enabler_if<std::is_floating_point<FloatType>::value>::type = sprout::enabler>
inline SPROUT_CONSTEXPR FloatType template<typename FloatType, typename Char>
inline SPROUT_CONSTEXPR typename std::enable_if<
std::is_floating_point<FloatType>::value,
FloatType
>::type
str_to_float(Char const* str) { str_to_float(Char const* str) {
return sprout::detail::str_to_float<FloatType>(str); return sprout::detail::str_to_float<FloatType>(str);
} }

View file

@ -3,13 +3,14 @@
#include <cstddef> #include <cstddef>
#include <cstdlib> #include <cstdlib>
#if !defined(_MSC_VER)
# include <cinttypes> # include <cinttypes>
#endif
#include <limits> #include <limits>
#include <type_traits> #include <type_traits>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/iterator/operation.hpp> #include <sprout/iterator/operation.hpp>
#include <sprout/ctype/ascii.hpp> #include <sprout/ctype/ascii.hpp>
#include <sprout/type_traits/enabler_if.hpp>
#include <sprout/detail/char_conversion.hpp> #include <sprout/detail/char_conversion.hpp>
namespace sprout { namespace sprout {
@ -60,8 +61,11 @@ namespace sprout {
) )
; ;
} }
template<typename IntType, typename CStrIterator, typename sprout::enabler_if<std::is_unsigned<IntType>::value>::type = sprout::enabler> template<typename IntType, typename CStrIterator>
inline SPROUT_CONSTEXPR IntType inline SPROUT_CONSTEXPR typename std::enable_if<
std::is_unsigned<IntType>::value,
IntType
>::type
str_to_int(CStrIterator str, int base) { str_to_int(CStrIterator str, int base) {
return sprout::ascii::isspace(*str) return sprout::ascii::isspace(*str)
? sprout::detail::str_to_int<IntType>(sprout::next(str), base) ? sprout::detail::str_to_int<IntType>(sprout::next(str), base)
@ -70,8 +74,11 @@ namespace sprout {
: sprout::detail::str_to_int_impl<IntType>(str, base, false) : sprout::detail::str_to_int_impl<IntType>(str, base, false)
; ;
} }
template<typename IntType, typename CStrIterator, typename sprout::enabler_if<std::is_signed<IntType>::value>::type = sprout::enabler> template<typename IntType, typename CStrIterator>
inline SPROUT_CONSTEXPR IntType inline SPROUT_CONSTEXPR typename std::enable_if<
std::is_signed<IntType>::value,
IntType
>::type
str_to_int(CStrIterator str, int base) { str_to_int(CStrIterator str, int base) {
return sprout::ascii::isspace(*str) return sprout::ascii::isspace(*str)
? sprout::detail::str_to_int<IntType>(sprout::next(str), base) ? sprout::detail::str_to_int<IntType>(sprout::next(str), base)
@ -85,6 +92,13 @@ namespace sprout {
template<typename IntType, typename CStrIterator, typename CharPtr> template<typename IntType, typename CStrIterator, typename CharPtr>
inline SPROUT_CONSTEXPR IntType inline SPROUT_CONSTEXPR IntType
str_to_int(CStrIterator str, CharPtr* endptr, int base) { str_to_int(CStrIterator str, CharPtr* endptr, int base) {
#if defined(_MSC_VER)
return !endptr ? sprout::detail::str_to_int<IntType>(str, base)
: std::is_signed<IntType>::value
? static_cast<IntType>(std::strtol(&*str, endptr, base))
: static_cast<IntType>(std::strtoul(&*str, endptr, base))
;
#else
return !endptr ? sprout::detail::str_to_int<IntType>(str, base) return !endptr ? sprout::detail::str_to_int<IntType>(str, base)
: std::is_signed<IntType>::value : std::is_signed<IntType>::value
? sizeof(IntType) <= sizeof(long) ? static_cast<IntType>(std::strtol(&*str, endptr, base)) ? sizeof(IntType) <= sizeof(long) ? static_cast<IntType>(std::strtol(&*str, endptr, base))
@ -94,24 +108,36 @@ namespace sprout {
: sizeof(IntType) <= sizeof(unsigned long long) ? static_cast<IntType>(std::strtoull(&*str, endptr, base)) : sizeof(IntType) <= sizeof(unsigned long long) ? static_cast<IntType>(std::strtoull(&*str, endptr, base))
: static_cast<IntType>(std::strtoumax(&*str, endptr, base)) : static_cast<IntType>(std::strtoumax(&*str, endptr, base))
; ;
#endif
} }
} // namespace detail } // namespace detail
// //
// str_to_int // str_to_int
// //
template<typename IntType, typename Char, typename sprout::enabler_if<std::is_integral<IntType>::value>::type = sprout::enabler> template<typename IntType, typename Char>
inline SPROUT_CONSTEXPR IntType inline SPROUT_CONSTEXPR typename std::enable_if<
std::is_integral<IntType>::value,
IntType
>::type
str_to_int(Char const* str, Char** endptr, int base = 10) { str_to_int(Char const* str, Char** endptr, int base = 10) {
return sprout::detail::str_to_int<IntType>(str, endptr, base); return sprout::detail::str_to_int<IntType>(str, endptr, base);
} }
template<typename IntType, typename Char, typename sprout::enabler_if<std::is_integral<IntType>::value>::type = sprout::enabler>
inline SPROUT_CONSTEXPR IntType template<typename IntType, typename Char>
inline SPROUT_CONSTEXPR typename std::enable_if<
std::is_integral<IntType>::value,
IntType
>::type
str_to_int(Char const* str, std::nullptr_t endptr, int base = 10) { str_to_int(Char const* str, std::nullptr_t endptr, int base = 10) {
return sprout::detail::str_to_int<IntType>(str, base); return sprout::detail::str_to_int<IntType>(str, base);
} }
template<typename IntType, typename Char, typename sprout::enabler_if<std::is_integral<IntType>::value>::type = sprout::enabler>
inline SPROUT_CONSTEXPR IntType template<typename IntType, typename Char>
inline SPROUT_CONSTEXPR typename std::enable_if<
std::is_integral<IntType>::value,
IntType
>::type
str_to_int(Char const* str, int base = 10) { str_to_int(Char const* str, int base = 10) {
return sprout::detail::str_to_int<IntType>(str, base); return sprout::detail::str_to_int<IntType>(str, base);
} }

View file

@ -4,15 +4,49 @@
#include <iterator> #include <iterator>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/iterator/operation.hpp> #include <sprout/iterator/operation.hpp>
#include HDR_ITERATOR_SSCRISK_CEL_OR_SPROUT
#include HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT #include HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT
namespace sprout { namespace sprout {
namespace detail { namespace detail {
template<typename RandomAccessIterator, typename BinaryPredicate>
inline SPROUT_CONSTEXPR typename std::iterator_traits<RandomAccessIterator>::difference_type
overlap_count_impl_ra(
RandomAccessIterator first, RandomAccessIterator last, BinaryPredicate pred,
typename std::iterator_traits<RandomAccessIterator>::difference_type pivot
)
{
return pivot == 0 ? (pred(*first, *last) ? 1 : 0)
: sprout::detail::overlap_count_impl_ra(
first, sprout::next(first, pivot), pred,
pivot / 2
)
+ sprout::detail::overlap_count_impl_ra(
sprout::next(first, pivot), last, pred,
(NS_SSCRISK_CEL_OR_SPROUT::distance(first, last) - pivot) / 2
)
;
}
template<typename RandomAccessIterator, typename BinaryPredicate>
inline SPROUT_CONSTEXPR typename std::iterator_traits<RandomAccessIterator>::difference_type
overlap_count(
RandomAccessIterator first, RandomAccessIterator last, BinaryPredicate pred,
std::random_access_iterator_tag*
)
{
return first == last || NS_SSCRISK_CEL_OR_SPROUT::distance(first, last) == 1 ? 0
: sprout::detail::overlap_count_impl_ra(
first, sprout::next(first, NS_SSCRISK_CEL_OR_SPROUT::distance(first, last) - 1), pred,
(NS_SSCRISK_CEL_OR_SPROUT::distance(first, last) - 1) / 2
)
;
}
template<typename InputIterator, typename BinaryPredicate> template<typename InputIterator, typename BinaryPredicate>
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type
overlap_count_impl( overlap_count_impl(
InputIterator first, InputIterator last, InputIterator first, InputIterator last, BinaryPredicate pred,
BinaryPredicate pred, typename std::iterator_traits<InputIterator>::value_type const& value typename std::iterator_traits<InputIterator>::value_type const& value
) )
{ {
return first == last ? 0 return first == last ? 0
@ -20,6 +54,17 @@ namespace sprout {
: sprout::detail::overlap_count_impl(sprout::next(first), last, pred, *first) : sprout::detail::overlap_count_impl(sprout::next(first), last, pred, *first)
; ;
} }
template<typename InputIterator, typename BinaryPredicate>
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type
overlap_count_impl(
InputIterator first, InputIterator last, BinaryPredicate pred,
void*
)
{
return first == last ? 0
: sprout::detail::overlap_count_impl(sprout::next(first), last, pred, *first)
;
}
// //
// overlap_count // overlap_count
@ -27,9 +72,8 @@ namespace sprout {
template<typename InputIterator, typename BinaryPredicate> template<typename InputIterator, typename BinaryPredicate>
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type
overlap_count(InputIterator first, InputIterator last, BinaryPredicate pred) { overlap_count(InputIterator first, InputIterator last, BinaryPredicate pred) {
return first == last ? 0 typedef typename std::iterator_traits<InputIterator>::iterator_category* category;
: sprout::detail::overlap_count_impl(sprout::next(first), last, pred, *first) return sprout::detail::overlap_count(first, last, pred, category());
;
} }
template<typename InputIterator> template<typename InputIterator>

View file

@ -28,10 +28,17 @@ namespace sprout_generator_detail {
static std::true_type test(int); static std::true_type test(int);
static std::false_type test(...); static std::false_type test(...);
}; };
#if defined(_MSC_VER)
template<typename T, typename Base_ = decltype(sprout_generator_detail::has_adl_generated_value_test<T>::test(0))>
struct has_adl_generated_value
: public Base_
{};
#else
template<typename T> template<typename T>
struct has_adl_generated_value struct has_adl_generated_value
: public decltype(sprout_generator_detail::has_adl_generated_value_test<T>::test(0)) : public decltype(sprout_generator_detail::has_adl_generated_value_test<T>::test(0))
{}; {};
#endif
template<typename T> template<typename T>
struct has_mem_generated_value_test { struct has_mem_generated_value_test {
@ -43,10 +50,17 @@ namespace sprout_generator_detail {
static std::true_type test(int); static std::true_type test(int);
static std::false_type test(...); static std::false_type test(...);
}; };
#if defined(_MSC_VER)
template<typename T, typename Base_ = decltype(sprout_generator_detail::has_mem_generated_value_test<T>::test(0))>
struct has_mem_generated_value
: public Base_
{};
#else
template<typename T> template<typename T>
struct has_mem_generated_value struct has_mem_generated_value
: public decltype(sprout_generator_detail::has_mem_generated_value_test<T>::test(0)) : public decltype(sprout_generator_detail::has_mem_generated_value_test<T>::test(0))
{}; {};
#endif
template<typename T> template<typename T>
struct has_get_generated_value_test { struct has_get_generated_value_test {
@ -58,10 +72,17 @@ namespace sprout_generator_detail {
static std::true_type test(int); static std::true_type test(int);
static std::false_type test(...); static std::false_type test(...);
}; };
#if defined(_MSC_VER)
template<typename T, typename Base_ = decltype(sprout_generator_detail::has_get_generated_value_test<T>::test(0))>
struct has_get_generated_value
: public Base_
{};
#else
template<typename T> template<typename T>
struct has_get_generated_value struct has_get_generated_value
: public decltype(sprout_generator_detail::has_get_generated_value_test<T>::test(0)) : public decltype(sprout_generator_detail::has_get_generated_value_test<T>::test(0))
{}; {};
#endif
template<typename T, typename Enable = void> template<typename T, typename Enable = void>
struct select_adl_generated_value; struct select_adl_generated_value;

View file

@ -28,10 +28,17 @@ namespace sprout_generator_detail {
static std::true_type test(int); static std::true_type test(int);
static std::false_type test(...); static std::false_type test(...);
}; };
#if defined(_MSC_VER)
template<typename T, typename Base_ = decltype(sprout_generator_detail::has_adl_next_generator_test<T>::test(0))>
struct has_adl_next_generator
: public Base_
{};
#else
template<typename T> template<typename T>
struct has_adl_next_generator struct has_adl_next_generator
: public decltype(sprout_generator_detail::has_adl_next_generator_test<T>::test(0)) : public decltype(sprout_generator_detail::has_adl_next_generator_test<T>::test(0))
{}; {};
#endif
template<typename T> template<typename T>
struct has_mem_next_generator_test { struct has_mem_next_generator_test {
@ -43,10 +50,17 @@ namespace sprout_generator_detail {
static std::true_type test(int); static std::true_type test(int);
static std::false_type test(...); static std::false_type test(...);
}; };
#if defined(_MSC_VER)
template<typename T, typename Base_ = decltype(sprout_generator_detail::has_mem_next_generator_test<T>::test(0))>
struct has_mem_next_generator
: public Base_
{};
#else
template<typename T> template<typename T>
struct has_mem_next_generator struct has_mem_next_generator
: public decltype(sprout_generator_detail::has_mem_next_generator_test<T>::test(0)) : public decltype(sprout_generator_detail::has_mem_next_generator_test<T>::test(0))
{}; {};
#endif
template<typename T> template<typename T>
struct has_get_next_generator_test { struct has_get_next_generator_test {
@ -58,10 +72,17 @@ namespace sprout_generator_detail {
static std::true_type test(int); static std::true_type test(int);
static std::false_type test(...); static std::false_type test(...);
}; };
#if defined(_MSC_VER)
template<typename T, typename Base_ = decltype(sprout_generator_detail::has_get_next_generator_test<T>::test(0))>
struct has_get_next_generator
: public Base_
{};
#else
template<typename T> template<typename T>
struct has_get_next_generator struct has_get_next_generator
: public decltype(sprout_generator_detail::has_get_next_generator_test<T>::test(0)) : public decltype(sprout_generator_detail::has_get_next_generator_test<T>::test(0))
{}; {};
#endif
template<typename T, typename Enable = void> template<typename T, typename Enable = void>
struct select_adl_next_generator; struct select_adl_next_generator;

View file

@ -120,10 +120,17 @@ namespace sprout_tuple_detail {
static std::true_type test(int); static std::true_type test(int);
static std::false_type test(...); static std::false_type test(...);
}; };
#if defined(_MSC_VER)
template<std::size_t I, typename T, typename Base_ = decltype(sprout_tuple_detail::has_adl_tuple_get_test<I, T>::test(0))>
struct has_adl_tuple_get
: public Base_
{};
#else
template<std::size_t I, typename T> template<std::size_t I, typename T>
struct has_adl_tuple_get struct has_adl_tuple_get
: public decltype(sprout_tuple_detail::has_adl_tuple_get_test<I, T>::test(0)) : public decltype(sprout_tuple_detail::has_adl_tuple_get_test<I, T>::test(0))
{}; {};
#endif
template<std::size_t I, typename T> template<std::size_t I, typename T>
struct has_std_get_test { struct has_std_get_test {
@ -135,10 +142,17 @@ namespace sprout_tuple_detail {
static std::true_type test(int); static std::true_type test(int);
static std::false_type test(...); static std::false_type test(...);
}; };
#if defined(_MSC_VER)
template<std::size_t I, typename T, typename Base_ = decltype(sprout_tuple_detail::has_std_get_test<I, T>::test(0))>
struct has_std_get
: public Base_
{};
#else
template<std::size_t I, typename T> template<std::size_t I, typename T>
struct has_std_get struct has_std_get
: public decltype(sprout_tuple_detail::has_std_get_test<I, T>::test(0)) : public decltype(sprout_tuple_detail::has_std_get_test<I, T>::test(0))
{}; {};
#endif
template<std::size_t I, typename T, typename Enable = void> template<std::size_t I, typename T, typename Enable = void>
struct select_adl_tuple_get; struct select_adl_tuple_get;

View file

@ -9,6 +9,17 @@
// SPROUT_HAS_XXX_TYPE_DEF // SPROUT_HAS_XXX_TYPE_DEF
// SPROUT_HAS_XXX_TYPE_DEF_LAZY // SPROUT_HAS_XXX_TYPE_DEF_LAZY
// //
#if defined(_MSC_VER)
#define SPROUT_HAS_XXX_TYPE_DEF(NAME, TYPE) \
template<typename T, typename = typename T::TYPE> \
std::true_type SPROUT_PP_CAT(SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_has_xxx_impl_check_type_, TYPE), NAME), __LINE__)(int); \
template<typename T> \
std::false_type SPROUT_PP_CAT(SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_has_xxx_impl_check_type_, TYPE), NAME), __LINE__)(long); \
template<typename T, typename Base_ = decltype(SPROUT_PP_CAT(SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_has_xxx_impl_check_type_, TYPE), NAME), __LINE__)<T>(0))> \
struct NAME \
: public Base_ \
{}
#else
#define SPROUT_HAS_XXX_TYPE_DEF(NAME, TYPE) \ #define SPROUT_HAS_XXX_TYPE_DEF(NAME, TYPE) \
template<typename T, typename = typename T::TYPE> \ template<typename T, typename = typename T::TYPE> \
std::true_type SPROUT_PP_CAT(SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_has_xxx_impl_check_type_, TYPE), NAME), __LINE__)(int); \ std::true_type SPROUT_PP_CAT(SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_has_xxx_impl_check_type_, TYPE), NAME), __LINE__)(int); \
@ -16,8 +27,9 @@
std::false_type SPROUT_PP_CAT(SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_has_xxx_impl_check_type_, TYPE), NAME), __LINE__)(long); \ std::false_type SPROUT_PP_CAT(SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_has_xxx_impl_check_type_, TYPE), NAME), __LINE__)(long); \
template<typename T> \ template<typename T> \
struct NAME \ struct NAME \
: decltype(SPROUT_PP_CAT(SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_has_xxx_impl_check_type_, TYPE), NAME), __LINE__)<T>(0)) \ : public decltype(SPROUT_PP_CAT(SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_has_xxx_impl_check_type_, TYPE), NAME), __LINE__)<T>(0)) \
{} {}
#endif
#define SPROUT_HAS_XXX_TYPE_DEF_LAZY(TYPE) \ #define SPROUT_HAS_XXX_TYPE_DEF_LAZY(TYPE) \
SPROUT_HAS_XXX_TYPE_DEF(SPROUT_PP_CAT(has_, TYPE), TYPE) SPROUT_HAS_XXX_TYPE_DEF(SPROUT_PP_CAT(has_, TYPE), TYPE)
@ -25,6 +37,17 @@
// SPROUT_HAS_XXX_VALUE_DEF // SPROUT_HAS_XXX_VALUE_DEF
// SPROUT_HAS_XXX_VALUE_DEF_LAZY // SPROUT_HAS_XXX_VALUE_DEF_LAZY
// //
#if defined(_MSC_VER)
#define SPROUT_HAS_XXX_VALUE_DEF(NAME, VALUE) \
template<typename T, decltype(&T::VALUE) = &T::VALUE> \
std::true_type SPROUT_PP_CAT(SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_has_xxx_impl_check_value_, VALUE), NAME), __LINE__)(int); \
template<typename T> \
std::false_type SPROUT_PP_CAT(SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_has_xxx_impl_check_value_, VALUE), NAME), __LINE__)(long); \
template<typename T, typename Base_ = decltype(SPROUT_PP_CAT(SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_has_xxx_impl_check_value_, VALUE), NAME), __LINE__)<T>(0))> \
struct NAME \
: public Base_ \
{}
#else
#define SPROUT_HAS_XXX_VALUE_DEF(NAME, VALUE) \ #define SPROUT_HAS_XXX_VALUE_DEF(NAME, VALUE) \
template<typename T, decltype(&T::VALUE) = &T::VALUE> \ template<typename T, decltype(&T::VALUE) = &T::VALUE> \
std::true_type SPROUT_PP_CAT(SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_has_xxx_impl_check_value_, VALUE), NAME), __LINE__)(int); \ std::true_type SPROUT_PP_CAT(SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_has_xxx_impl_check_value_, VALUE), NAME), __LINE__)(int); \
@ -32,8 +55,9 @@
std::false_type SPROUT_PP_CAT(SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_has_xxx_impl_check_value_, VALUE), NAME), __LINE__)(long); \ std::false_type SPROUT_PP_CAT(SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_has_xxx_impl_check_value_, VALUE), NAME), __LINE__)(long); \
template<typename T> \ template<typename T> \
struct NAME \ struct NAME \
: decltype(SPROUT_PP_CAT(SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_has_xxx_impl_check_value_, VALUE), NAME), __LINE__)<T>(0)) \ : public decltype(SPROUT_PP_CAT(SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_has_xxx_impl_check_value_, VALUE), NAME), __LINE__)<T>(0)) \
{} {}
#endif
#define SPROUT_HAS_XXX_VALUE_DEF_LAZY(VALUE) \ #define SPROUT_HAS_XXX_VALUE_DEF_LAZY(VALUE) \
SPROUT_HAS_XXX_VALUE_DEF(SPROUT_PP_CAT(has_, VALUE), VALUE) SPROUT_HAS_XXX_VALUE_DEF(SPROUT_PP_CAT(has_, VALUE), VALUE)