fix: index_tuple metafunctions as index_tuple aliases (if Template-aliases enabled)

This commit is contained in:
bolero-MURAKAMI 2013-05-12 11:05:31 +09:00
parent 57011669a0
commit c71502f6b6
11 changed files with 111 additions and 45 deletions

17
sprout/detail/sizeof.hpp Normal file
View file

@ -0,0 +1,17 @@
#ifndef SPROUT_DETAIL_SIZEOF_HPP
#define SPROUT_DETAIL_SIZEOF_HPP
#include <cstddef>
#include <type_traits>
#include <sprout/config.hpp>
namespace sprout {
namespace detail {
template<typename... Ts>
struct sizeof_pack
: public std::integral_constant<std::size_t, sizeof...(Ts)>
{};
} // namespace detail
} // namespace sprout
#endif // #ifndef SPROUT_DETAIL_SIZEOF_HPP

View file

@ -5,7 +5,6 @@
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/index_tuple/index_tuple.hpp> #include <sprout/index_tuple/index_tuple.hpp>
#include <sprout/index_tuple/integer_n.hpp> #include <sprout/index_tuple/integer_n.hpp>
#include <sprout/index_tuple/enable_make_indexes.hpp>
namespace sprout { namespace sprout {
// //
@ -21,18 +20,14 @@ namespace sprout {
#else // #if SPROUT_USE_TEMPLATE_ALIASES #else // #if SPROUT_USE_TEMPLATE_ALIASES
template<sprout::index_t I, std::size_t N> template<sprout::index_t I, std::size_t N>
struct index_n struct index_n
: public sprout::enable_make_indexes< : public typename sprout::integer_n<sprout::index_t, I, N>::type
typename sprout::integer_n<sprout::index_t, I, N>::type ::template transfer<sprout::index_tuple<> >
::template transfer<sprout::index_tuple<> >
>
{}; {};
template<sprout::uindex_t I, std::size_t N> template<sprout::uindex_t I, std::size_t N>
struct uindex_n struct uindex_n
: public sprout::enable_make_indexes< : public typename sprout::integer_n<sprout::uindex_t, I, N>::type
typename sprout::integer_n<sprout::uindex_t, I, N>::type ::template transfer<sprout::uindex_tuple<> >
::template transfer<sprout::uindex_tuple<> >
>
{}; {};
#endif // #if SPROUT_USE_TEMPLATE_ALIASES #endif // #if SPROUT_USE_TEMPLATE_ALIASES
} // namespace sprout } // namespace sprout

View file

@ -4,7 +4,6 @@
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/index_tuple/index_tuple.hpp> #include <sprout/index_tuple/index_tuple.hpp>
#include <sprout/index_tuple/integer_range.hpp> #include <sprout/index_tuple/integer_range.hpp>
#include <sprout/index_tuple/enable_make_indexes.hpp>
namespace sprout { namespace sprout {
// //
@ -29,10 +28,8 @@ namespace sprout {
typename std::make_signed<sprout::index_t>::type Step = sprout::detail::integer_range_default_step<sprout::index_t, First, Last>::value typename std::make_signed<sprout::index_t>::type Step = sprout::detail::integer_range_default_step<sprout::index_t, First, Last>::value
> >
struct index_range struct index_range
: public sprout::enable_make_indexes< : public typename sprout::integer_range<sprout::index_t, First, Last, Step>::type
typename sprout::integer_range<sprout::index_t, First, Last, Step>::type ::template transfer<sprout::index_tuple<> >
::template transfer<sprout::index_tuple<> >
>
{}; {};
template< template<
@ -40,10 +37,8 @@ namespace sprout {
typename std::make_signed<sprout::uindex_t>::type Step = sprout::detail::integer_range_default_step<sprout::uindex_t, First, Last>::value typename std::make_signed<sprout::uindex_t>::type Step = sprout::detail::integer_range_default_step<sprout::uindex_t, First, Last>::value
> >
struct uindex_range struct uindex_range
: public sprout::enable_make_indexes< : public typename sprout::integer_range<sprout::uindex_t, First, Last, Step>::type
typename sprout::integer_range<sprout::uindex_t, First, Last, Step>::type ::template transfer<sprout::uindex_tuple<> >
::template transfer<sprout::uindex_tuple<> >
>
{}; {};
#endif // #if SPROUT_USE_TEMPLATE_ALIASES #endif // #if SPROUT_USE_TEMPLATE_ALIASES
} // namespace sprout } // namespace sprout

View file

@ -8,10 +8,15 @@ namespace sprout {
// //
// index_sequence_for // index_sequence_for
// //
#if SPROUT_USE_TEMPLATE_ALIASES
template<typename... Ts>
using index_sequence_for = sprout::uindex_pack<Ts...>;
#else // #if SPROUT_USE_TEMPLATE_ALIASES
template<typename... Ts> template<typename... Ts>
struct index_sequence_for struct index_sequence_for
: public sprout::uindex_pack<Ts...> : public sprout::uindex_pack<Ts...>
{}; {};
#endif // #if SPROUT_USE_TEMPLATE_ALIASES
} // namespace sprout } // namespace sprout
#endif // #ifndef SPROUT_INDEX_TUPLE_INDEX_SEQUENCE_FOR_HPP #endif // #ifndef SPROUT_INDEX_TUPLE_INDEX_SEQUENCE_FOR_HPP

View file

@ -27,6 +27,10 @@ namespace sprout {
struct rebind struct rebind
: public index_tuple<J...> : public index_tuple<J...>
{}; {};
public:
static SPROUT_CONSTEXPR type make() SPROUT_NOEXCEPT {
return type();
}
}; };
template<sprout::uindex_t... Indexes> template<sprout::uindex_t... Indexes>
@ -39,6 +43,10 @@ namespace sprout {
struct rebind struct rebind
: public uindex_tuple<J...> : public uindex_tuple<J...>
{}; {};
public:
static SPROUT_CONSTEXPR type make() SPROUT_NOEXCEPT {
return type();
}
}; };
#endif // #if SPROUT_USE_TEMPLATE_ALIASES #endif // #if SPROUT_USE_TEMPLATE_ALIASES
} // namespace sprout } // namespace sprout

View file

@ -61,13 +61,26 @@ namespace sprout {
I I
> >
{}; {};
template<typename T, T I, std::size_t N>
struct integer_n
: public sprout::enable_make_indexes<
sprout::detail::integer_n_impl<T, I, N>
>
{};
} // namespace detail } // namespace detail
//
// integer_range
//
#if SPROUT_USE_TEMPLATE_ALIASES
template<typename T, T I, std::size_t N>
using integer_n = typename sprout::detail::integer_n<T, I, N>::type;
#else // #if SPROUT_USE_TEMPLATE_ALIASES
template<typename T, T I, std::size_t N> template<typename T, T I, std::size_t N>
struct integer_n struct integer_n
: public sprout::enable_make_indexes< : public sprout::detail::integer_n<T, I, N>
sprout::detail::integer_n_impl<T, I, N>
>
{}; {};
#endif // #if SPROUT_USE_TEMPLATE_ALIASES
} // namespace sprout } // namespace sprout
#endif // #ifndef SPROUT_INDEX_TUPLE_INTEGER_N_HPP #endif // #ifndef SPROUT_INDEX_TUPLE_INTEGER_N_HPP

View file

@ -2,16 +2,22 @@
#define SPROUT_INDEX_TUPLE_INTEGER_PACK_HPP #define SPROUT_INDEX_TUPLE_INTEGER_PACK_HPP
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/detail/sizeof.hpp>
#include <sprout/index_tuple/make_integer_sequence.hpp> #include <sprout/index_tuple/make_integer_sequence.hpp>
namespace sprout { namespace sprout {
// //
// integer_pack // integer_pack
// //
#if SPROUT_USE_TEMPLATE_ALIASES
template<typename T, typename... Ts>
using integer_pack = sprout::make_integer_sequence<T, sprout::detail::sizeof_pack<Ts...>::value>;
#else // #if SPROUT_USE_TEMPLATE_ALIASES
template<typename T, typename... Ts> template<typename T, typename... Ts>
struct integer_pack struct integer_pack
: public sprout::make_integer_sequence<T, sizeof...(Ts)> : public sprout::make_integer_sequence<T, sizeof...(Ts)>
{}; {};
#endif // #if SPROUT_USE_TEMPLATE_ALIASES
} // namespace sprout } // namespace sprout
#endif // #ifndef SPROUT_INDEX_TUPLE_INTEGER_PACK_HPP #endif // #ifndef SPROUT_INDEX_TUPLE_INTEGER_PACK_HPP

View file

@ -30,71 +30,87 @@ namespace sprout {
{}; {};
template<typename T, T First, typename std::make_signed<T>::type Step, typename std::make_unsigned<T>::type N, typename Enable = void> template<typename T, T First, typename std::make_signed<T>::type Step, typename std::make_unsigned<T>::type N, typename Enable = void>
struct integer_range_impl; struct integer_range_dispatch;
template<typename T, T First, typename std::make_signed<T>::type Step, typename std::make_unsigned<T>::type N> template<typename T, T First, typename std::make_signed<T>::type Step, typename std::make_unsigned<T>::type N>
struct integer_range_impl< struct integer_range_dispatch<
T, First, Step, N, T, First, Step, N,
typename std::enable_if<(N == 0)>::type typename std::enable_if<(N == 0)>::type
> >
: public sprout::integer_sequence<T> : public sprout::integer_sequence<T>
{}; {};
template<typename T, T First, typename std::make_signed<T>::type Step, typename std::make_unsigned<T>::type N> template<typename T, T First, typename std::make_signed<T>::type Step, typename std::make_unsigned<T>::type N>
struct integer_range_impl< struct integer_range_dispatch<
T, First, Step, N, T, First, Step, N,
typename std::enable_if<(N == 1)>::type typename std::enable_if<(N == 1)>::type
> >
: public sprout::integer_sequence<T, First> : public sprout::integer_sequence<T, First>
{}; {};
template<typename T, T First, typename std::make_signed<T>::type Step, typename std::make_unsigned<T>::type N> template<typename T, T First, typename std::make_signed<T>::type Step, typename std::make_unsigned<T>::type N>
struct integer_range_impl< struct integer_range_dispatch<
T, First, Step, N, T, First, Step, N,
typename std::enable_if<(N > 1 && N % 2 == 0)>::type typename std::enable_if<(N > 1 && N % 2 == 0)>::type
> >
: public sprout::detail::integer_range_next_even< : public sprout::detail::integer_range_next_even<
T, typename sprout::detail::integer_range_impl<T, First, Step, N / 2>::type, T, typename sprout::detail::integer_range_dispatch<T, First, Step, N / 2>::type,
N / 2 * Step N / 2 * Step
> >
{}; {};
template<typename T, T First, typename std::make_signed<T>::type Step, typename std::make_unsigned<T>::type N> template<typename T, T First, typename std::make_signed<T>::type Step, typename std::make_unsigned<T>::type N>
struct integer_range_impl< struct integer_range_dispatch<
T, First, Step, N, T, First, Step, N,
typename std::enable_if<(N > 1 && N % 2 == 1)>::type typename std::enable_if<(N > 1 && N % 2 == 1)>::type
> >
: public sprout::detail::integer_range_next_odd< : public sprout::detail::integer_range_next_odd<
T, typename sprout::detail::integer_range_impl<T, First, Step, N / 2>::type, T, typename sprout::detail::integer_range_dispatch<T, First, Step, N / 2>::type,
N / 2 * Step, First + (N - 1) * Step N / 2 * Step, First + (N - 1) * Step
> >
{}; {};
template<typename T, T First, T Last, typename std::make_signed<T>::type Step, typename Enable = void> template<typename T, T First, T Last, typename std::make_signed<T>::type Step, typename Enable = void>
struct integer_range {}; struct integer_range_impl {};
template<typename T, T First, T Last, typename std::make_signed<T>::type Step> template<typename T, T First, T Last, typename std::make_signed<T>::type Step>
struct integer_range< struct integer_range_impl<
T, First, Last, Step, T, First, Last, Step,
typename std::enable_if<((First < Last && Step > 0) || (First > Last && Step < 0) || (First == Last))>::type typename std::enable_if<((First < Last && Step > 0) || (First > Last && Step < 0) || (First == Last))>::type
> >
: public sprout::detail::integer_range_impl< : public sprout::detail::integer_range_dispatch<
T, First, Step, T, First, Step,
(static_cast<typename std::make_signed<T>::type>(Last - First) + (Step > 0 ? Step - 1 : Step + 1)) / Step (static_cast<typename std::make_signed<T>::type>(Last - First) + (Step > 0 ? Step - 1 : Step + 1)) / Step
> >
{}; {};
template<
typename T, T First, T Last,
typename std::make_signed<T>::type Step
>
struct integer_range
: public sprout::enable_make_indexes<
sprout::detail::integer_range_impl<T, First, Last, Step>
>
{
static_assert(
(First < Last && Step > 0) || (First > Last && Step < 0) || (First == Last),
"(First < Last && Step > 0) || (First > Last && Step < 0) || (First == Last)"
);
};
} // namespace detail } // namespace detail
// //
// integer_range // integer_range
// //
#if SPROUT_USE_TEMPLATE_ALIASES
template<
typename T, T First, T Last,
typename std::make_signed<T>::type Step = sprout::detail::integer_range_default_step<T, First, Last>::value
>
using integer_range = typename sprout::detail::integer_range<T, First, Last, Step>::type;
#else // #if SPROUT_USE_TEMPLATE_ALIASES
template< template<
typename T, T First, T Last, typename T, T First, T Last,
typename std::make_signed<T>::type Step = sprout::detail::integer_range_default_step<T, First, Last>::value typename std::make_signed<T>::type Step = sprout::detail::integer_range_default_step<T, First, Last>::value
> >
struct integer_range struct integer_range
: public sprout::enable_make_indexes< : public sprout::detail::integer_range<T, First, Last, Step>
sprout::detail::integer_range<T, First, Last, Step> {};
> #endif // #if SPROUT_USE_TEMPLATE_ALIASES
{
static_assert(
(First < Last && Step > 0) || (First > Last && Step < 0) || (First == Last),
"(First < Last && Step > 0) || (First > Last && Step < 0) || (First == Last)"
);
};
} // namespace sprout } // namespace sprout
#endif // #ifndef SPROUT_INDEX_TUPLE_INTEGER_RANGE_HPP #endif // #ifndef SPROUT_INDEX_TUPLE_INTEGER_RANGE_HPP

View file

@ -16,6 +16,10 @@ namespace sprout {
struct rebind struct rebind
: public integer_sequence<T, J...> : public integer_sequence<T, J...>
{}; {};
public:
static SPROUT_CONSTEXPR type make() SPROUT_NOEXCEPT {
return type();
}
public: public:
typedef T value_type; typedef T value_type;
template<typename Seq> template<typename Seq>
@ -25,7 +29,7 @@ namespace sprout {
public: public:
SPROUT_STATIC_CONSTEXPR std::size_t static_size = sizeof...(Is); SPROUT_STATIC_CONSTEXPR std::size_t static_size = sizeof...(Is);
public: public:
static SPROUT_CONSTEXPR size_t size() noexcept { static SPROUT_CONSTEXPR size_t size() SPROUT_NOEXCEPT {
return static_size; return static_size;
} }
}; };

View file

@ -9,10 +9,15 @@ namespace sprout {
// //
// make_index_sequence // make_index_sequence
// //
#if SPROUT_USE_TEMPLATE_ALIASES
template<sprout::uindex_t N>
using make_index_sequence = sprout::make_uindex_tuple<N>;
#else // #if SPROUT_USE_TEMPLATE_ALIASES
template<sprout::uindex_t N> template<sprout::uindex_t N>
struct make_index_sequence struct make_index_sequence
: public sprout::make_uindex_tuple<N> : public sprout::make_uindex_tuple<N>
{}; {};
#endif // #if SPROUT_USE_TEMPLATE_ALIASES
} // namespace sprout } // namespace sprout
#endif // #ifndef SPROUT_INDEX_TUPLE_MAKE_INDEX_SEQUENCE_HPP #endif // #ifndef SPROUT_INDEX_TUPLE_MAKE_INDEX_SEQUENCE_HPP

View file

@ -3,18 +3,20 @@
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/index_tuple/integer_range.hpp> #include <sprout/index_tuple/integer_range.hpp>
#include <sprout/index_tuple/enable_make_indexes.hpp>
namespace sprout { namespace sprout {
// //
// make_integer_sequence // make_integer_sequence
// //
#if SPROUT_USE_TEMPLATE_ALIASES
template<typename T, T N>
using make_integer_sequence = sprout::integer_range<T, 0, N>;
#else // #if SPROUT_USE_TEMPLATE_ALIASES
template<typename T, T N> template<typename T, T N>
struct make_integer_sequence struct make_integer_sequence
: public sprout::enable_make_indexes< : public sprout::integer_range<T, 0, N>
sprout::integer_range<T, 0, N>
>
{}; {};
#endif // #if SPROUT_USE_TEMPLATE_ALIASES
} // namespace sprout } // namespace sprout
#endif // #ifndef SPROUT_INDEX_TUPLE_MAKE_INTEGER_SEQUENCE_HPP #endif // #ifndef SPROUT_INDEX_TUPLE_MAKE_INTEGER_SEQUENCE_HPP