add def/spectrum, dft/sinusoid

fix container_traits defined weak typedefs and constants
fix reverse_iterator
This commit is contained in:
bolero-MURAKAMI 2012-04-30 10:55:33 +09:00
parent 3d10fd9f18
commit 3e5facb754
14 changed files with 443 additions and 54 deletions

View file

@ -19,8 +19,7 @@ namespace sprout {
//
template<typename T, std::size_t N>
struct container_traits<sscrisk::cel::array<T, N> >
: public sprout::detail::container_traits_default_types<sscrisk::cel::array<T, N> >
, public sprout::detail::container_traits_default_size<sscrisk::cel::array<T, N> >
: public sprout::detail::container_traits_default<sscrisk::cel::array<T, N> >
{
public:
typedef sprout::index_iterator<sscrisk::cel::array<T, N>&> iterator;

View file

@ -3,31 +3,72 @@
#include <cstddef>
#include <array>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/type_traits/has_xxx.hpp>
#include <sprout/type_traits/inherit_if_xxx.hpp>
namespace sprout {
//
// container_traits
//
template<typename Container>
struct container_traits;
namespace detail {
//
// inherit_if_value_type
// inherit_if_iterator
// inherit_if_const_iterator
// inherit_if_reference
// inherit_if_const_reference
// inherit_if_size_type
// inherit_if_difference_type
// inherit_if_pointer
// inherit_if_static_size
//
SPROUT_INHERIT_IF_XXX_TYPE_DEF_LAZY(value_type);
SPROUT_INHERIT_IF_XXX_TYPE_DEF_LAZY(iterator);
SPROUT_INHERIT_IF_XXX_TYPE_DEF_LAZY(const_iterator);
SPROUT_INHERIT_IF_XXX_TYPE_DEF_LAZY(reference);
SPROUT_INHERIT_IF_XXX_TYPE_DEF_LAZY(const_reference);
SPROUT_INHERIT_IF_XXX_TYPE_DEF_LAZY(size_type);
SPROUT_INHERIT_IF_XXX_TYPE_DEF_LAZY(difference_type);
SPROUT_INHERIT_IF_XXX_TYPE_DEF_LAZY(pointer);
SPROUT_INHERIT_IF_XXX_TYPE_DEF_LAZY(const_pointer);
SPROUT_INHERIT_IF_XXX_CONSTANT_DEF_LAZY(static_size);
//
// has_static_size
//
SPROUT_HAS_XXX_VALUE_DEF_LAZY(static_size);
template<typename Container, typename Enable = void>
struct inherit_if_fixed_size {};
template<typename Container>
struct container_traits_default_types {
struct inherit_if_fixed_size<
Container,
typename std::enable_if<sprout::detail::has_static_size<Container>::value>::type
> {
public:
typedef typename Container::value_type value_type;
typedef typename Container::iterator iterator;
typedef typename Container::const_iterator const_iterator;
typedef typename Container::reference reference;
typedef typename Container::const_reference const_reference;
typedef typename Container::size_type size_type;
typedef typename Container::difference_type difference_type;
typedef typename Container::pointer pointer;
typedef typename Container::const_pointer const_pointer;
static SPROUT_CONSTEXPR decltype(Container::static_size) fixed_size() {
return Container::static_size;
}
};
template<typename Container>
struct container_traits_default
: public sprout::detail::inherit_if_value_type<Container>
, public sprout::detail::inherit_if_iterator<Container>
, public sprout::detail::inherit_if_const_iterator<Container>
, public sprout::detail::inherit_if_reference<Container>
, public sprout::detail::inherit_if_const_reference<Container>
, public sprout::detail::inherit_if_size_type<Container>
, public sprout::detail::inherit_if_difference_type<Container>
, public sprout::detail::inherit_if_pointer<Container>
, public sprout::detail::inherit_if_const_pointer<Container>
, public sprout::detail::inherit_if_static_size<Container>
, public sprout::detail::inherit_if_fixed_size<Container>
{};
template<typename T, std::size_t N>
struct container_traits_default_types<T[N]> {
struct container_traits_default<T[N]> {
public:
typedef T value_type;
typedef T* iterator;
@ -38,36 +79,21 @@ namespace sprout {
typedef std::ptrdiff_t difference_type;
typedef T* pointer;
typedef T const* const_pointer;
};
template<typename Container>
struct container_traits_default_size {
public:
SPROUT_STATIC_CONSTEXPR typename sprout::detail::container_traits_default_types<Container>::size_type static_size
= std::tuple_size<Container>::value
;
SPROUT_STATIC_CONSTEXPR size_type static_size = N ;
public:
static SPROUT_CONSTEXPR typename sprout::detail::container_traits_default_types<Container>::size_type fixed_size() {
return static_size;
}
};
template<typename T, std::size_t N>
struct container_traits_default_size<T[N]> {
public:
SPROUT_STATIC_CONSTEXPR typename sprout::detail::container_traits_default_types<T[N]>::size_type static_size
= N
;
public:
static SPROUT_CONSTEXPR typename sprout::detail::container_traits_default_types<T[N]>::size_type fixed_size() {
static SPROUT_CONSTEXPR size_type fixed_size() {
return static_size;
}
};
} // namespace detail
//
// container_traits
//
template<typename Container>
struct container_traits
: public sprout::detail::container_traits_default_types<Container>
, public sprout::detail::container_traits_default_size<Container>
: public sprout::detail::container_traits_default<Container>
{};
template<typename Container>
struct container_traits<Container const>
@ -81,8 +107,7 @@ namespace sprout {
template<typename T, std::size_t N>
struct container_traits<T[N]>
: public sprout::detail::container_traits_default_types<T[N]>
, public sprout::detail::container_traits_default_size<T[N]>
: public sprout::detail::container_traits_default<T[N]>
{};
template<typename T, std::size_t N>
struct container_traits<T const[N]>

View file

@ -238,7 +238,11 @@ namespace sprout {
//
template<typename Container>
SPROUT_CONSTEXPR typename std::iterator_traits<sprout::index_iterator<Container> >::difference_type
distance(sprout::index_iterator<Container> first, sprout::index_iterator<Container> last) {
distance(
sprout::index_iterator<Container> first,
sprout::index_iterator<Container> last
)
{
return last - first;
}
} // namespace sprout

View file

@ -6,6 +6,7 @@
#include <sprout/config.hpp>
#include <sprout/iterator/next.hpp>
#include <sprout/iterator/prev.hpp>
#include <sprout/iterator/distance.hpp>
namespace sprout {
//
@ -100,13 +101,19 @@ namespace sprout {
SPROUT_CONSTEXPR reference operator[](difference_type n) const {
return *(deref_tmp - n);
}
SPROUT_CONSTEXPR reverse_iterator next() const {
return reverse_iterator(sprout::prev(current));
}
SPROUT_CONSTEXPR reverse_iterator prev() const {
return reverse_iterator(sprout::next(current));
}
void swap(reverse_iterator& other) {
using std::swap;
swap(current, other.current);
swap(deref_tmp, other.deref_tmp);
}
};
template <typename Iterator1, typename Iterator2>
template<typename Iterator1, typename Iterator2>
SPROUT_CONSTEXPR bool operator==(
sprout::reverse_iterator<Iterator1> const& lhs,
sprout::reverse_iterator<Iterator2> const& rhs
@ -114,7 +121,7 @@ namespace sprout {
{
return lhs.base() == rhs.base();
}
template <typename Iterator1, typename Iterator2>
template<typename Iterator1, typename Iterator2>
SPROUT_CONSTEXPR bool operator!=(
sprout::reverse_iterator<Iterator1> const& lhs,
sprout::reverse_iterator<Iterator2> const& rhs
@ -122,7 +129,7 @@ namespace sprout {
{
return !(lhs == rhs);
}
template <typename Iterator1, typename Iterator2>
template<typename Iterator1, typename Iterator2>
SPROUT_CONSTEXPR bool operator<(
sprout::reverse_iterator<Iterator1> const& lhs,
sprout::reverse_iterator<Iterator2> const& rhs
@ -130,7 +137,7 @@ namespace sprout {
{
return lhs.base() < rhs.base();
}
template <typename Iterator1, typename Iterator2>
template<typename Iterator1, typename Iterator2>
SPROUT_CONSTEXPR bool operator>(
sprout::reverse_iterator<Iterator1> const& lhs,
sprout::reverse_iterator<Iterator2> const& rhs
@ -138,7 +145,7 @@ namespace sprout {
{
return rhs < lhs;
}
template <typename Iterator1, typename Iterator2>
template<typename Iterator1, typename Iterator2>
SPROUT_CONSTEXPR bool operator<=(
sprout::reverse_iterator<Iterator1> const& lhs,
sprout::reverse_iterator<Iterator2> const& rhs
@ -146,7 +153,7 @@ namespace sprout {
{
return !(rhs < lhs);
}
template <typename Iterator1, typename Iterator2>
template<typename Iterator1, typename Iterator2>
SPROUT_CONSTEXPR bool operator>=(
sprout::reverse_iterator<Iterator1> const& lhs,
sprout::reverse_iterator<Iterator2> const& rhs
@ -154,15 +161,15 @@ namespace sprout {
{
return !(lhs < rhs);
}
template <typename Iterator1, typename Iterator2>
template<typename Iterator1, typename Iterator2>
SPROUT_CONSTEXPR auto operator-(
sprout::reverse_iterator<Iterator1> const& lhs,
sprout::reverse_iterator<Iterator2> const& rhs
) -> decltype(lhs.current - rhs.current)
) -> decltype(lhs.base() - rhs.base())
{
return lhs.current - rhs.current;
return lhs.base() - rhs.base();
}
template <typename Iterator>
template<typename Iterator>
SPROUT_CONSTEXPR sprout::reverse_iterator<Iterator> operator+(
typename sprout::reverse_iterator<Iterator>::difference_type n,
sprout::reverse_iterator<Iterator> const& it
@ -178,7 +185,57 @@ namespace sprout {
void swap(sprout::reverse_iterator<Iterator>& lhs, sprout::reverse_iterator<Iterator>& rhs) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(lhs.swap(rhs))) {
lhs.swap(rhs);
}
//
// next
//
template<typename Iterator>
SPROUT_CONSTEXPR sprout::reverse_iterator<Iterator> next(
sprout::reverse_iterator<Iterator> const& it
)
{
return it.next();
}
template<typename Iterator>
SPROUT_CONSTEXPR sprout::reverse_iterator<Iterator> next(
sprout::reverse_iterator<Iterator> const& it,
typename sprout::reverse_iterator<Iterator>::difference_type n
)
{
return it + n;
}
//
// prev
//
template<typename Iterator>
SPROUT_CONSTEXPR sprout::reverse_iterator<Iterator> prev(
sprout::reverse_iterator<Iterator> const& it
)
{
return it.prev();
}
template<typename Iterator>
SPROUT_CONSTEXPR sprout::reverse_iterator<Iterator> prev(
sprout::reverse_iterator<Iterator> const& it,
typename sprout::reverse_iterator<Iterator>::difference_type n
)
{
return it - n;
}
//
// distance
//
template<typename Iterator>
SPROUT_CONSTEXPR typename std::iterator_traits<sprout::reverse_iterator<Iterator> >::difference_type
distance(
sprout::reverse_iterator<Iterator> first,
sprout::reverse_iterator<Iterator> last
)
{
return last - first;
}
} // namespace sprout
#endif // #ifndef SPROUT_ITERATOR_REVERSE_ITERATOR_HPP

View file

@ -6,6 +6,7 @@
#include <sprout/numeric/dft/idft.hpp>
#include <sprout/numeric/dft/dft_element.hpp>
#include <sprout/numeric/dft/idft_element.hpp>
#include <sprout/numeric/dft/spectrum.hpp>
#include <sprout/numeric/dft/sinusoid.hpp>
#endif // #ifndef SPROUT_NUMERIC_DFT_HPP

View file

@ -0,0 +1,44 @@
#ifndef SPROUT_NUMERIC_DFT_FIT_SINUSOID_HPP
#define SPROUT_NUMERIC_DFT_FIT_SINUSOID_HPP
#include <sprout/config.hpp>
#include <sprout/container/traits.hpp>
#include <sprout/container/functions.hpp>
#include <sprout/numeric/dft/fixed/sinusoid.hpp>
#include <sprout/algorithm/fit/result_of.hpp>
#include <sprout/sub_array.hpp>
namespace sprout {
namespace fit {
namespace detail {
template<typename Container>
inline SPROUT_CONSTEXPR typename sprout::fit::result_of::algorithm<Container>::type sinusoid_impl(
Container const& cont,
typename sprout::container_traits<Container>::value_type const& frequency,
typename sprout::container_traits<Container>::value_type const& amplitude,
typename sprout::container_traits<Container>::difference_type offset
)
{
return sprout::sub_copy(
sprout::get_internal(sprout::fixed::sinusoid(cont, frequency, amplitude)),
offset,
offset + sprout::size(cont)
);
}
} // namespace detail
//
// sinusoid
//
template<typename Container>
inline SPROUT_CONSTEXPR typename sprout::fit::result_of::algorithm<Container>::type sinusoid(
Container const& cont,
typename sprout::container_traits<Container>::value_type const& frequency = 1,
typename sprout::container_traits<Container>::value_type const& amplitude = 1
)
{
return sprout::fit::detail::sinusoid_impl(cont, frequency, amplitude, sprout::internal_begin_offset(cont));
}
} // namespace fit
} // namespace sprout
#endif // #ifndef SPROUT_NUMERIC_DFT_FIT_SINUSOID_HPP

View file

@ -0,0 +1,46 @@
#ifndef SPROUT_NUMERIC_DFT_FIT_SPECTRUM_HPP
#define SPROUT_NUMERIC_DFT_FIT_SPECTRUM_HPP
#include <sprout/config.hpp>
#include <sprout/container/traits.hpp>
#include <sprout/container/functions.hpp>
#include <sprout/numeric/dft/fixed/spectrum.hpp>
#include <sprout/algorithm/fit/result_of.hpp>
#include <sprout/sub_array.hpp>
#include HDR_ALGORITHM_SSCRISK_CEL_OR_SPROUT
#include HDR_ITERATOR_SSCRISK_CEL_OR_SPROUT
namespace sprout {
namespace fit {
namespace detail {
template<typename InputIterator, typename Result>
inline SPROUT_CONSTEXPR typename sprout::fit::result_of::algorithm<Result>::type spectrum_impl(
InputIterator first,
InputIterator last,
Result const& result,
typename sprout::container_traits<Result>::difference_type offset
)
{
return sprout::sub_copy(
sprout::get_internal(sprout::fixed::spectrum(first, last, result)),
offset,
offset + NS_SSCRISK_CEL_OR_SPROUT::min(NS_SSCRISK_CEL_OR_SPROUT::distance(first, last), sprout::size(result))
);
}
} // namespace detail
//
// spectrum
//
template<typename InputIterator, typename Result>
inline SPROUT_CONSTEXPR typename sprout::fit::result_of::algorithm<Result>::type spectrum(
InputIterator first,
InputIterator last,
Result const& result
)
{
return sprout::fit::detail::spectrum_impl(first, last, result, sprout::internal_begin_offset(result));
}
} // namespace fit
} // namespace sprout
#endif // #ifndef SPROUT_NUMERIC_DFT_FIT_SPECTRUM_HPP

View file

@ -0,0 +1,75 @@
#ifndef SPROUT_NUMERIC_DFT_FIXED_SINUSOID_HPP
#define SPROUT_NUMERIC_DFT_FIXED_SINUSOID_HPP
#include <cmath>
#include <sprout/config.hpp>
#include <sprout/index_tuple.hpp>
#include <sprout/container/traits.hpp>
#include <sprout/container/functions.hpp>
#include <sprout/container/indexes.hpp>
#include <sprout/algorithm/fixed/result_of.hpp>
#include <sprout/math/constants.hpp>
namespace sprout {
namespace fixed {
namespace detail {
template<typename Container, sprout::index_t... Indexes>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Container>::type
sinusoid_impl(
Container const& cont,
typename sprout::container_traits<Container>::value_type const& d,
typename sprout::container_traits<Container>::value_type const& amplitude,
sprout::index_tuple<Indexes...>,
typename sprout::container_traits<Container>::difference_type offset,
typename sprout::container_traits<Container>::size_type size
)
{
typedef typename sprout::container_traits<Container>::value_type value_type;
using std::sin;
return sprout::remake<Container>(
cont,
size,
(Indexes >= offset && Indexes < offset + size
? amplitude * sin(d * value_type(Indexes))
: *sprout::next(sprout::internal_begin(cont), Indexes)
)...
);
}
template<typename Container>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Container>::type
sinusoid(
Container const& cont,
typename sprout::container_traits<Container>::value_type const& frequency,
typename sprout::container_traits<Container>::value_type const& amplitude
)
{
typedef typename sprout::container_traits<Container>::value_type value_type;
return sprout::fixed::detail::sinusoid_impl(
cont,
value_type(2) * sprout::math::pi<value_type>() * frequency / value_type(sprout::size(cont)),
amplitude,
sprout::container_indexes<Container>::make(),
sprout::internal_begin_offset(cont),
sprout::size(cont)
);
}
} // namespace detail
//
// sinusoid
//
template<typename Container>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Container>::type
sinusoid(
Container const& cont,
typename sprout::container_traits<Container>::value_type const& frequency = 1,
typename sprout::container_traits<Container>::value_type const& amplitude = 1
)
{
return sprout::fixed::detail::sinusoid(cont, frequency, amplitude);
}
} // namespace fixed
using sprout::fixed::sinusoid;
} // namespace sprout
#endif // #ifndef SPROUT_NUMERIC_DFT_FIXED_SINUSOID_HPP

View file

@ -0,0 +1,81 @@
#ifndef SPROUT_NUMERIC_DFT_FIXED_SPECTRUM_HPP
#define SPROUT_NUMERIC_DFT_FIXED_SPECTRUM_HPP
#include <cmath>
#include <complex>
#include <sprout/config.hpp>
#include <sprout/index_tuple.hpp>
#include <sprout/container/traits.hpp>
#include <sprout/container/functions.hpp>
#include <sprout/iterator/operation.hpp>
#include <sprout/algorithm/fixed/result_of.hpp>
#include HDR_ITERATOR_SSCRISK_CEL_OR_SPROUT
namespace sprout {
namespace fixed {
namespace detail {
template<typename InputIterator, typename Result, sprout::index_t... Indexes>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Result>::type
spectrum_impl(
InputIterator first,
InputIterator last,
Result const& result,
sprout::index_tuple<Indexes...>,
typename sprout::container_traits<Result>::difference_type offset,
typename sprout::container_traits<Result>::size_type size,
typename sprout::container_traits<Result>::size_type input_size
)
{
using std::sqrt;
using std::real;
using std::imag;
return sprout::remake<Result>(
result,
size,
(Indexes >= offset && Indexes < offset + size && Indexes < offset + input_size
? sqrt(
real(*sprout::next(first, Indexes)) * real(*sprout::next(first, Indexes))
+ imag(*sprout::next(first, Indexes)) * imag(*sprout::next(first, Indexes))
)
: *sprout::next(sprout::internal_begin(result), Indexes)
)...
);
}
template<typename InputIterator, typename Result>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Result>::type
spectrum(
InputIterator first,
InputIterator last,
Result const& result
)
{
return sprout::fixed::detail::spectrum_impl(
first,
last,
result,
typename sprout::index_range<0, sprout::container_traits<Result>::static_size>::type(),
sprout::internal_begin_offset(result),
sprout::size(result),
NS_SSCRISK_CEL_OR_SPROUT::distance(first, last)
);
}
} // namespace detail
//
// spectrum
//
template<typename InputIterator, typename Result>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Result>::type
spectrum(
InputIterator first,
InputIterator last,
Result const& result
)
{
return sprout::fixed::detail::spectrum(first, last, result);
}
} // namespace fixed
using sprout::fixed::spectrum;
} // namespace sprout
#endif // #ifndef SPROUT_NUMERIC_DFT_FIXED_SPECTRUM_HPP

View file

@ -0,0 +1,8 @@
#ifndef SPROUT_NUMERIC_DFT_SINUSOID_HPP
#define SPROUT_NUMERIC_DFT_SINUSOID_HPP
#include <sprout/config.hpp>
#include <sprout/numeric/dft/fixed/sinusoid.hpp>
#include <sprout/numeric/dft/fit/sinusoid.hpp>
#endif // #ifndef SPROUT_NUMERIC_DFT_SINUSOID_HPP

View file

@ -0,0 +1,8 @@
#ifndef SPROUT_NUMERIC_DFT_SPECTRUM_HPP
#define SPROUT_NUMERIC_DFT_SPECTRUM_HPP
#include <sprout/config.hpp>
#include <sprout/numeric/dft/fixed/spectrum.hpp>
#include <sprout/numeric/dft/fit/spectrum.hpp>
#endif // #ifndef SPROUT_NUMERIC_DFT_SPECTRUM_HPP

View file

@ -137,7 +137,7 @@ namespace sprout {
//
template<typename Iterator>
struct container_traits<sprout::range::range_container<Iterator> >
: public sprout::detail::container_traits_default_types<sprout::range::range_container<Iterator> >
: public sprout::detail::container_traits_default<sprout::range::range_container<Iterator> >
{};
} // namespace sprout

View file

@ -15,7 +15,7 @@
std::false_type SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_has_xxx_impl_check_type_, TYPE), __LINE__)(long); \
template<typename T> \
struct NAME \
: decltype(SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_has_xxx_impl_check_type_, TYPE), __LINE__)<T>( 0 ) ) \
: decltype(SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_has_xxx_impl_check_type_, TYPE), __LINE__)<T>(0)) \
{}
//
@ -24,4 +24,23 @@
#define SPROUT_HAS_XXX_TYPE_DEF_LAZY(TYPE) \
SPROUT_HAS_XXX_TYPE_DEF(SPROUT_PP_CAT(has_, TYPE), TYPE)
//
// SPROUT_HAS_XXX_VALUE_DEF
//
#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_has_xxx_impl_check_value_, VALUE), __LINE__)(int); \
template<typename T> \
std::false_type SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_has_xxx_impl_check_value_, VALUE), __LINE__)(long); \
template<typename T> \
struct NAME \
: decltype(SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_has_xxx_impl_check_value_, VALUE), __LINE__)<T>(0)) \
{}
//
// SPROUT_HAS_XXX_VALUE_DEF_LAZY
//
#define SPROUT_HAS_XXX_VALUE_DEF_LAZY(VALUE) \
SPROUT_HAS_XXX_TYPE_DEF(SPROUT_PP_CAT(has_, VALUE), VALUE)
#endif // #ifndef SPROUT_TYPE_TRAITS_HAS_XXX_HPP

View file

@ -28,4 +28,26 @@
#define SPROUT_INHERIT_IF_XXX_TYPE_DEF_LAZY(TYPE) \
SPROUT_INHERIT_IF_XXX_TYPE_DEF(SPROUT_PP_CAT(inherit_if_, TYPE), TYPE)
//
// SPROUT_INHERIT_IF_XXX_CONSTANT_DEF
//
#define SPROUT_INHERIT_IF_XXX_CONSTANT_DEF(NAME, CONSTANT) \
SPROUT_HAS_XXX_VALUE_DEF(SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_inherit_if_xxx_constant_def_impl_has_, CONSTANT), __LINE__), CONSTANT); \
template<typename T, typename Enable = void> \
struct NAME {}; \
template<typename T> \
struct NAME< \
T, \
typename std::enable_if<SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_inherit_if_xxx_constant_def_impl_has_, CONSTANT), __LINE__)<T>::value>::type \
> { \
public: \
SPROUT_STATIC_CONSTEXPR decltype(T::CONSTANT) CONSTANT = T::CONSTANT; \
}
//
// SPROUT_INHERIT_IF_XXX_CONSTANT_DEF_LAZY
//
#define SPROUT_INHERIT_IF_XXX_CONSTANT_DEF_LAZY(CONSTANT) \
SPROUT_INHERIT_IF_XXX_CONSTANT_DEF(SPROUT_PP_CAT(inherit_if_, CONSTANT), CONSTANT)
#endif // #ifndef SPROUT_TYPE_TRAITS_INHERIT_IF_XXX_HPP