1 // The Art of C++ / Sequences
2 // Copyright (c) 2015-2016 Daniel Frey
3 
4 #ifndef TAOCPP_SEQUENCES_INCLUDE_SUM_HPP
5 #define TAOCPP_SEQUENCES_INCLUDE_SUM_HPP
6 
7 #include <type_traits>
8 #include <utility>
9 
10 #include "integer_sequence.hpp"
11 #include "config.hpp"
12 
13 #ifndef TAOCPP_FOLD_EXPRESSIONS
14 #include <cstddef>
15 #include "make_integer_sequence.hpp"
16 #endif
17 
18 namespace tao
19 {
20   namespace seq
21   {
22 
23 #ifdef TAOCPP_FOLD_EXPRESSIONS
24 
25     template< typename T, T... Ns >
26     struct sum
27       : std::integral_constant< T, ( Ns + ... + T( 0 ) ) >
28     {};
29 
30 #else
31 
32     namespace impl
33     {
34       template< std::size_t, std::size_t N >
35       struct chars
36       {
37         char dummy[ N + 1 ];
38       };
39 
40       template< typename, std::size_t... >
41       struct collector;
42 
43       template< std::size_t... Is, std::size_t... Ns >
44       struct collector< index_sequence< Is... >, Ns... >
45         : chars< Is, Ns >...
46       {};
47 
48       template< std::size_t N, typename T, T... Ns >
49       struct sum
50       {
51         using type = std::integral_constant<
52           T,
53           T( sizeof( collector< make_index_sequence< N >, ( ( Ns > 0 ) ? Ns : 0 )... > ) - N ) -
54           T( sizeof( collector< make_index_sequence< N >, ( ( Ns < 0 ) ? -Ns : 0 )... > ) - N ) >;
55       };
56     }
57 
58     template< typename T, T... Ns >
59     struct sum
60       : impl::sum< sizeof...( Ns ) + 1, T, Ns..., 0 >::type
61     {};
62 
63 #endif
64 
65     template< typename T, T... Ns >
66     struct sum< integer_sequence< T, Ns... > >
67       : sum< T, Ns... >
68     {};
69   }
70 }
71 
72 #endif // TAOCPP_SEQUENCES_INCLUDE_SUM_HPP
73