Skip to content

Commit

Permalink
Update sequences
Browse files Browse the repository at this point in the history
  • Loading branch information
d-frey committed Jan 21, 2018
1 parent a263d2c commit 2138a00
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 49 deletions.
20 changes: 10 additions & 10 deletions include/tao/seq/config.hpp
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
// The Art of C++ / Sequences
// Copyright (c) 2015-2018 Daniel Frey
// Copyright (c) 2015-2017 Daniel Frey
// Please see LICENSE for license or visit https://github.com/taocpp/sequences/

#ifndef TAOCPP_SEQUENCES_INCLUDE_CONFIG_HPP
#define TAOCPP_SEQUENCES_INCLUDE_CONFIG_HPP

#if __cplusplus >= 201402L

#define TAOCPP_USE_STD_INTEGER_SEQUENCE
#endif

#if( __cplusplus >= 201402L ) && defined( _LIBCPP_VERSION )
#if defined( _LIBCPP_VERSION )
#define TAOCPP_USE_STD_MAKE_INTEGER_SEQUENCE
#elif defined( _GLIBCXX_RELEASE ) && ( _GLIBCXX_RELEASE >= 8 )
#define TAOCPP_USE_STD_MAKE_INTEGER_SEQUENCE
#elif defined( _MSC_VER ) && ( _MSC_VER >= 190023918 )
#define TAOCPP_USE_STD_MAKE_INTEGER_SEQUENCE
#endif

#endif // __cplusplus >= 201402L

#if defined( __cpp_fold_expressions )
#define TAOCPP_FOLD_EXPRESSIONS
#elif __cplusplus > 201402L
#if defined( __apple_build_version__ ) && ( __clang_major__ >= 7 )
#define TAOCPP_FOLD_EXPRESSIONS
#elif defined( __clang__ ) && ( ( __clang_major__ > 3 ) || ( ( __clang_major__ == 3 ) && ( __clang_minor__ >= 6 ) ) )
#define TAOCPP_FOLD_EXPRESSIONS
#endif
#endif

#endif // TAOCPP_SEQUENCES_INCLUDE_CONFIG_HPP
4 changes: 2 additions & 2 deletions include/tao/seq/exclusive_scan.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// The Art of C++ / Sequences
// Copyright (c) 2015-2018 Daniel Frey
// Copyright (c) 2015-2017 Daniel Frey
// Please see LICENSE for license or visit https://github.com/taocpp/sequences/

#ifndef TAOCPP_SEQUENCES_INCLUDE_EXCLUSIVE_SCAN_HPP
#define TAOCPP_SEQUENCES_INCLUDE_EXCLUSIVE_SCAN_HPP
Expand Down
4 changes: 2 additions & 2 deletions include/tao/seq/integer_sequence.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// The Art of C++ / Sequences
// Copyright (c) 2015-2018 Daniel Frey
// Copyright (c) 2015-2017 Daniel Frey
// Please see LICENSE for license or visit https://github.com/taocpp/sequences/

#ifndef TAOCPP_SEQUENCES_INCLUDE_INTEGER_SEQUENCE_HPP
#define TAOCPP_SEQUENCES_INCLUDE_INTEGER_SEQUENCE_HPP
Expand Down
57 changes: 30 additions & 27 deletions include/tao/seq/make_integer_sequence.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// The Art of C++ / Sequences
// Copyright (c) 2015-2018 Daniel Frey
// Copyright (c) 2015-2017 Daniel Frey
// Please see LICENSE for license or visit https://github.com/taocpp/sequences/

#ifndef TAOCPP_SEQUENCES_INCLUDE_MAKE_INTEGER_SEQUENCE_HPP
#define TAOCPP_SEQUENCES_INCLUDE_MAKE_INTEGER_SEQUENCE_HPP
Expand All @@ -24,52 +24,55 @@ namespace tao

#else

// idea from http://stackoverflow.com/a/13073076

namespace impl
{
template< typename, std::size_t, bool >
struct double_up;
// we have four instantiations of generate_sequence<>, independent of T or N.
// V is the current bit, E is the end marker - if true, this is the last step.
template< bool V, bool E >
struct generate_sequence;

template< typename T, T... Ns, std::size_t N >
struct double_up< integer_sequence< T, Ns... >, N, false >
// last step: generate final integer sequence
template<>
struct generate_sequence< false, true >
{
using type = integer_sequence< T, Ns..., ( N + Ns )... >;
template< typename T, T M, T N, std::size_t S, T... Ns >
using f = integer_sequence< T, Ns... >;
};

template< typename T, T... Ns, std::size_t N >
struct double_up< integer_sequence< T, Ns... >, N, true >
template<>
struct generate_sequence< true, true >
{
using type = integer_sequence< T, Ns..., ( N + Ns )..., 2 * N >;
template< typename T, T M, T N, std::size_t S, T... Ns >
using f = integer_sequence< T, Ns..., S >;
};

template< typename T, T N, typename = void >
struct generate_sequence;

template< typename T, T N >
using generate_sequence_t = typename generate_sequence< T, N >::type;

template< typename T, T N, typename >
struct generate_sequence
: double_up< generate_sequence_t< T, N / 2 >, N / 2, N % 2 == 1 >
// intermediate step: double existing values, append one more if V is set.
template<>
struct generate_sequence< false, false >
{
template< typename T, T M, T N, std::size_t S, T... Ns >
using f = typename generate_sequence< ( N & ( M / 2 ) ) != 0, ( M / 2 ) == 0 >::template f< T, M / 2, N, 2 * S, Ns..., ( Ns + S )... >;
};

template< typename T, T N >
struct generate_sequence< T, N, typename std::enable_if< ( N == 0 ) >::type >
template<>
struct generate_sequence< true, false >
{
using type = integer_sequence< T >;
template< typename T, T M, T N, std::size_t S, T... Ns >
using f = typename generate_sequence< ( N & ( M / 2 ) ) != 0, ( M / 2 ) == 0 >::template f< T, M / 2, N, 2 * S + 1, Ns..., ( Ns + S )..., 2 * S >;
};

// the final sequence per T/N should be memoized, it will probably be used multiple times.
// also checks the limit and starts the above generator properly.
template< typename T, T N >
struct generate_sequence< T, N, typename std::enable_if< ( N == 1 ) >::type >
struct memoize_sequence
{
using type = integer_sequence< T, 0 >;
static_assert( N < T( 1 << 20 ), "N too large" );
using type = typename generate_sequence< false, false >::template f< T, ( N < T( 1 << 1 ) ) ? T( 1 << 1 ) : ( N < T( 1 << 2 ) ) ? T( 1 << 2 ) : ( N < T( 1 << 3 ) ) ? T( 1 << 3 ) : ( N < T( 1 << 4 ) ) ? T( 1 << 4 ) : ( N < T( 1 << 5 ) ) ? T( 1 << 5 ) : ( N < T( 1 << 6 ) ) ? T( 1 << 6 ) : ( N < T( 1 << 7 ) ) ? T( 1 << 7 ) : ( N < T( 1 << 8 ) ) ? T( 1 << 8 ) : ( N < T( 1 << 9 ) ) ? T( 1 << 9 ) : ( N < T( 1 << 10 ) ) ? T( 1 << 10 ) : T( 1 << 20 ), N, 0 >;
};
}

template< typename T, T N >
using make_integer_sequence = impl::generate_sequence_t< T, N >;
using make_integer_sequence = typename impl::memoize_sequence< T, N >::type;

template< std::size_t N >
using make_index_sequence = make_integer_sequence< std::size_t, N >;
Expand Down
4 changes: 2 additions & 2 deletions include/tao/seq/partial_sum.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// The Art of C++ / Sequences
// Copyright (c) 2015-2018 Daniel Frey
// Copyright (c) 2015-2017 Daniel Frey
// Please see LICENSE for license or visit https://github.com/taocpp/sequences/

#ifndef TAOCPP_SEQUENCES_INCLUDE_PARTIAL_SUM_HPP
#define TAOCPP_SEQUENCES_INCLUDE_PARTIAL_SUM_HPP
Expand Down
17 changes: 11 additions & 6 deletions include/tao/seq/sum.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// The Art of C++ / Sequences
// Copyright (c) 2015-2018 Daniel Frey
// Copyright (c) 2015-2017 Daniel Frey
// Please see LICENSE for license or visit https://github.com/taocpp/sequences/

#ifndef TAOCPP_SEQUENCES_INCLUDE_SUM_HPP
#define TAOCPP_SEQUENCES_INCLUDE_SUM_HPP
Expand Down Expand Up @@ -47,17 +47,22 @@ namespace tao
{
};

template< std::size_t N, typename T, T... Ns >
template< bool, std::size_t N, typename T, T... Ns >
struct sum
{
using type = std::integral_constant< T,
T( sizeof( collector< make_index_sequence< N >, ( ( Ns > 0 ) ? Ns : 0 )... > ) - N ) - T( sizeof( collector< make_index_sequence< N >, ( ( Ns < 0 ) ? -Ns : 0 )... > ) - N ) >;
using type = std::integral_constant< T, T( sizeof( collector< make_index_sequence< N >, ( ( Ns > 0 ) ? Ns : 0 )... > ) - N ) - T( sizeof( collector< make_index_sequence< N >, ( ( Ns < 0 ) ? -Ns : 0 )... > ) - N ) >;
};

template< std::size_t N, typename T, T... Ns >
struct sum< true, N, T, Ns... >
{
using type = std::integral_constant< T, T( sizeof( collector< make_index_sequence< N >, ( ( Ns > 0 ) ? Ns : 0 )... > ) - N ) >;
};
}

template< typename T, T... Ns >
struct sum
: impl::sum< sizeof...( Ns ) + 1, T, Ns..., 0 >::type
: impl::sum< std::is_unsigned< T >::value, sizeof...( Ns ) + 1, T, Ns..., 0 >::type
{
};

Expand Down

0 comments on commit 2138a00

Please sign in to comment.