diff --git a/benchmark/foldable/CMakeLists.txt b/benchmark/foldable/CMakeLists.txt index b8012efa5..061a15b2b 100644 --- a/benchmark/foldable/CMakeLists.txt +++ b/benchmark/foldable/CMakeLists.txt @@ -3,17 +3,17 @@ # (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) foreach(method IN ITEMS count foldl foldl1 foldr foldr1 for_each length maximum maximum_by minimum minimum_by product sum unpack) - # Methods requiring `Integral` elements in the `Foldable`. + # Methods requiring integral `Constant`s (or stronger) in the `Foldable`. if(${method} MATCHES "maximum|minimum|product|sum") set(hana_tuple_env " ((1..50).to_a + (51..500).step(25).to_a).map { |n| xs = (1..n).to_a.map { |i| - \"boost::hana::integral\" + \"boost::hana::integral_constant\" }.join(', ') { setup: ' - #include + #include #include ', foldable: \"boost::hana::tuple(#{xs})\", @@ -25,13 +25,13 @@ foreach(method IN ITEMS count foldl foldl1 foldr foldr1 for_each length maximum set(std_tuple_env " ((1..50).to_a + (51..500).step(25).to_a).map { |n| xs = (1..n).to_a.map { |i| - \"boost::hana::integral\" + \"boost::hana::integral_constant\" }.join(', ') { setup: ' #include - #include + #include #include ', foldable: \"std::make_tuple(#{xs})\", diff --git a/benchmark/iterable/at.cpp b/benchmark/iterable/at.cpp index a055b73bd..5ba68b2d7 100644 --- a/benchmark/iterable/at.cpp +++ b/benchmark/iterable/at.cpp @@ -5,7 +5,7 @@ Distributed under the Boost Software License, Version 1.0. */ #include -#include +#include #include "benchmark.hpp" diff --git a/benchmark/iterable/drop.cpp b/benchmark/iterable/drop.cpp index 47f29b5f6..8f500afe2 100644 --- a/benchmark/iterable/drop.cpp +++ b/benchmark/iterable/drop.cpp @@ -5,7 +5,7 @@ Distributed under the Boost Software License, Version 1.0. */ #include -#include +#include #include "benchmark.hpp" diff --git a/benchmark/list/sort.cpp b/benchmark/list/sort.cpp index 2a562d06a..7c858ff30 100644 --- a/benchmark/list/sort.cpp +++ b/benchmark/list/sort.cpp @@ -5,7 +5,7 @@ Distributed under the Boost Software License, Version 1.0. */ #include -#include +#include #include "benchmark.hpp" diff --git a/benchmark/list/take.cpp b/benchmark/list/take.cpp index a543ad629..42c96e5bc 100644 --- a/benchmark/list/take.cpp +++ b/benchmark/list/take.cpp @@ -4,7 +4,7 @@ Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) */ -#include +#include #include #include "benchmark.hpp" diff --git a/benchmark/searchable/CMakeLists.txt b/benchmark/searchable/CMakeLists.txt index 87c11bd12..32766fc80 100644 --- a/benchmark/searchable/CMakeLists.txt +++ b/benchmark/searchable/CMakeLists.txt @@ -8,11 +8,11 @@ foreach(method IN ITEMS all any elem find lookup none subset) set(hana_tuple_env "((1..50).to_a + (51..500).step(25).to_a).map { |n| xs = (1..n).to_a.map { |i| - \"boost::hana::integral\" + \"boost::hana::integral_constant\" }.join(', ') { setup: ' - #include + #include #include ', searchable: \"boost::hana::tuple(#{xs})\", @@ -24,12 +24,12 @@ foreach(method IN ITEMS all any elem find lookup none subset) set(std_tuple_env "((1..50).to_a + (51..500).step(25).to_a).map { |n| xs = (1..n).to_a.map { |i| - \"boost::hana::integral\" + \"boost::hana::integral_constant\" }.join(', ') { setup: ' #include - #include + #include #include ', searchable: \"std::make_tuple(#{xs})\", diff --git a/example/constant.cpp b/example/constant.cpp index c5f6e8b99..71d7dd159 100644 --- a/example/constant.cpp +++ b/example/constant.cpp @@ -5,13 +5,13 @@ Distributed under the Boost Software License, Version 1.0. */ #include -#include +#include using namespace boost::hana; int main() { //! [value] - auto i = integral; // notice no constexpr + auto i = integral_constant; // notice no constexpr static_assert(value(i) == 3, "value(i) is always a constant expression!"); //! [value] } diff --git a/example/core/is_a.cpp b/example/core/is_a.cpp index bce18b82b..6d1e13ed5 100644 --- a/example/core/is_a.cpp +++ b/example/core/is_a.cpp @@ -10,7 +10,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include #include -#include +#include #include #include #include diff --git a/example/core/to.cpp b/example/core/to.cpp index 9e272a03f..5ef901ada 100644 --- a/example/core/to.cpp +++ b/example/core/to.cpp @@ -7,7 +7,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include #include -#include +#include #include #include diff --git a/example/cppcon_2014/functor.cpp b/example/cppcon_2014/functor.cpp index fc52e3ac1..a4fbe5899 100644 --- a/example/cppcon_2014/functor.cpp +++ b/example/cppcon_2014/functor.cpp @@ -6,7 +6,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include -#include +#include #include "matrix/comparable.hpp" #include "matrix/functor.hpp" diff --git a/example/cppcon_2014/matrix.cpp b/example/cppcon_2014/matrix.cpp index 006ba968b..9c46ed22c 100644 --- a/example/cppcon_2014/matrix.cpp +++ b/example/cppcon_2014/matrix.cpp @@ -5,7 +5,7 @@ Distributed under the Boost Software License, Version 1.0. */ #include -#include +#include #include "matrix/comparable.hpp" using namespace boost::hana; diff --git a/example/cppcon_2014/matrix/det.hpp b/example/cppcon_2014/matrix/det.hpp index a33258c71..c784418c9 100644 --- a/example/cppcon_2014/matrix/det.hpp +++ b/example/cppcon_2014/matrix/det.hpp @@ -16,7 +16,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include #include -#include +#include #include #include #include diff --git a/example/cppcon_2014/matrix/monoid.hpp b/example/cppcon_2014/matrix/monoid.hpp index c4f993d56..3ad0d7e35 100644 --- a/example/cppcon_2014/matrix/monoid.hpp +++ b/example/cppcon_2014/matrix/monoid.hpp @@ -11,7 +11,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include -#include +#include #include #include #include diff --git a/example/cppcon_2014/matrix/ring.hpp b/example/cppcon_2014/matrix/ring.hpp index fba15a842..f3df359e8 100644 --- a/example/cppcon_2014/matrix/ring.hpp +++ b/example/cppcon_2014/matrix/ring.hpp @@ -12,7 +12,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include #include -#include +#include #include #include #include diff --git a/example/either.cpp b/example/either.cpp index b0bcc98ed..aef96f129 100644 --- a/example/either.cpp +++ b/example/either.cpp @@ -8,7 +8,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include #include -#include +#include #include #include diff --git a/example/enumerable.cpp b/example/enumerable.cpp index e7ef64344..56686e9d6 100644 --- a/example/enumerable.cpp +++ b/example/enumerable.cpp @@ -5,7 +5,7 @@ Distributed under the Boost Software License, Version 1.0. */ #include -#include +#include using namespace boost::hana; diff --git a/example/ext/boost/mpl/vector/cheatsheet/fold.cpp b/example/ext/boost/mpl/vector/cheatsheet/fold.cpp index 2f355c174..7906f5d5d 100644 --- a/example/ext/boost/mpl/vector/cheatsheet/fold.cpp +++ b/example/ext/boost/mpl/vector/cheatsheet/fold.cpp @@ -8,7 +8,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include #include -#include +#include #include #include diff --git a/example/foldable.cpp b/example/foldable.cpp index dbb64a2ac..9a17ca67a 100644 --- a/example/foldable.cpp +++ b/example/foldable.cpp @@ -9,7 +9,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include #include -#include +#include #include #include #include diff --git a/example/functional/on/infix.cpp b/example/functional/on/infix.cpp index f79b81f4b..14c80084e 100644 --- a/example/functional/on/infix.cpp +++ b/example/functional/on/infix.cpp @@ -7,7 +7,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include #include -#include +#include #include #include #include diff --git a/example/group.cpp b/example/group.cpp index f1a947997..ed7622308 100644 --- a/example/group.cpp +++ b/example/group.cpp @@ -5,7 +5,7 @@ Distributed under the Boost Software License, Version 1.0. */ #include -#include +#include using namespace boost::hana; diff --git a/example/integer_list/foldable.cpp b/example/integer_list/foldable.cpp index fd14bdee3..e2b898e16 100644 --- a/example/integer_list/foldable.cpp +++ b/example/integer_list/foldable.cpp @@ -7,7 +7,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include #include -#include +#include using namespace boost::hana; diff --git a/example/integer_list/integer_list.cpp b/example/integer_list/integer_list.cpp index 6e546e92e..c0fad94d6 100644 --- a/example/integer_list/integer_list.cpp +++ b/example/integer_list/integer_list.cpp @@ -6,7 +6,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include -#include +#include #include using namespace boost::hana; diff --git a/example/integral.cpp b/example/integral.cpp deleted file mode 100644 index a77a63d20..000000000 --- a/example/integral.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/* -@copyright Louis Dionne 2014 -Distributed under the Boost Software License, Version 1.0. -(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) - */ - -#include -#include -using namespace boost::hana; - - -int main() { - //! [comparable] - BOOST_HANA_CONSTANT_CHECK(equal(int_<1>, int_<1>)); - BOOST_HANA_CONSTANT_CHECK(not_equal(int_<1>, int_<2>)); - - BOOST_HANA_CONSTANT_CHECK(equal(int_<1>, long_<1>)); - BOOST_HANA_CONSTANT_CHECK(not_equal(int_<1>, long_<2>)); - //! [comparable] - - //! [literals] - using namespace literals; // contains the _c suffix - - BOOST_HANA_CONSTANT_CHECK(1234_c == llong<1234>); - BOOST_HANA_CONSTANT_CHECK(-1234_c == llong<-1234>); - BOOST_HANA_CONSTANT_CHECK(1_c + (3_c * 4_c) == llong<1 + (3 * 4)>); - //! [literals] - - //! [operators] - BOOST_HANA_CONSTANT_CHECK(int_<1> + int_<3> == int_<4>); - - // Mixed-type operations are supported, but only when it involves a - // promotion, and not a conversion that could be lossy. - BOOST_HANA_CONSTANT_CHECK(size_t<3> * ushort<5> == size_t<15>); - BOOST_HANA_CONSTANT_CHECK(llong<15> == int_<15>); - //! [operators] - - //! [orderable] - BOOST_HANA_CONSTANT_CHECK(less(int_<-3>, int_<3>)); - BOOST_HANA_CONSTANT_CHECK(max(int_<-3>, long_<2>) == long_<2>); - BOOST_HANA_CONSTANT_CHECK(min(int_<-3>, long_<2>) == int_<-3>); - //! [orderable] -} diff --git a/example/integral_constant.cpp b/example/integral_constant.cpp new file mode 100644 index 000000000..c3426ad15 --- /dev/null +++ b/example/integral_constant.cpp @@ -0,0 +1,98 @@ +/* +@copyright Louis Dionne 2014 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + */ + +#include +#include +#include +#include + +#include +#include +using namespace boost::hana; + + +int main() { + +{ + +//! [operators] +BOOST_HANA_CONSTANT_CHECK(int_<1> + int_<3> == int_<4>); + +// Mixed-type operations are supported, but only when it involves a +// promotion, and not a conversion that could be lossy. +BOOST_HANA_CONSTANT_CHECK(size_t<3> * ushort<5> == size_t<15>); +BOOST_HANA_CONSTANT_CHECK(llong<15> == int_<15>); +//! [operators] + +}{ + +//! [times_loop_unrolling] +std::string s; +for (char c = 'x'; c <= 'z'; ++c) + int_<5>.times([&] { s += c; }); + +BOOST_HANA_RUNTIME_CHECK(s == "xxxxxyyyyyzzzzz"); +//! [times_loop_unrolling] + +}{ + +//! [as_static_member] +std::string s; +for (char c = 'x'; c <= 'z'; ++c) + decltype(int_<5>)::times([&] { s += c; }); + +BOOST_HANA_RUNTIME_CHECK(s == "xxxxxyyyyyzzzzz"); +//! [as_static_member] + +}{ + +//! [times_higher_order] +std::string s; +BOOST_HANA_CONSTEXPR_LAMBDA auto functions = tuple( + [&] { s += "x"; }, + [&] { s += "y"; }, + [&] { s += "z"; } +); +for_each(functions, int_<5>.times); +BOOST_HANA_RUNTIME_CHECK(s == "xxxxxyyyyyzzzzz"); +//! [times_higher_order] + +}{ + +//! [times_with_index_runtime] +std::vector v; +int_<5>.times.with_index([&](auto index) { v.push_back(index); }); + +BOOST_HANA_RUNTIME_CHECK(v == std::vector{0, 1, 2, 3, 4}); +//! [times_with_index_runtime] + +//! [times_with_index_compile_time] +constexpr auto xs = tuple(0, 1, 2); +int_<3>.times.with_index([xs](auto index) { + static_assert(xs[index] == index, ""); +}); +//! [times_with_index_compile_time] + +}{ + +//! [literals] +using namespace literals; // contains the _c suffix + +BOOST_HANA_CONSTANT_CHECK(1234_c == llong<1234>); +BOOST_HANA_CONSTANT_CHECK(-1234_c == llong<-1234>); +BOOST_HANA_CONSTANT_CHECK(1_c + (3_c * 4_c) == llong<1 + (3 * 4)>); +//! [literals] + +}{ + +//! [integral_constant] +BOOST_HANA_CONSTANT_CHECK(integral_constant == int_<2>); +static_assert(decltype(integral_constant)::value == 2, ""); +//! [integral_constant] + +} + +} diff --git a/example/integral_domain.cpp b/example/integral_domain.cpp index 9a68349d5..8bd5f8733 100644 --- a/example/integral_domain.cpp +++ b/example/integral_domain.cpp @@ -5,7 +5,7 @@ Distributed under the Boost Software License, Version 1.0. */ #include -#include +#include using namespace boost::hana; diff --git a/example/iterable.cpp b/example/iterable.cpp index 41f19742b..54a41dccb 100644 --- a/example/iterable.cpp +++ b/example/iterable.cpp @@ -7,7 +7,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include #include -#include +#include #include #include #include diff --git a/example/list.cpp b/example/list.cpp index 2741ddccc..d67060f78 100644 --- a/example/list.cpp +++ b/example/list.cpp @@ -9,7 +9,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include #include -#include +#include #include #include #include diff --git a/example/list/traversable.cpp b/example/list/traversable.cpp index a53c4b281..92fd47123 100644 --- a/example/list/traversable.cpp +++ b/example/list/traversable.cpp @@ -5,7 +5,7 @@ Distributed under the Boost Software License, Version 1.0. */ #include -#include +#include #include #include diff --git a/example/logical.cpp b/example/logical.cpp index 21ad91cf6..9a7e42bdf 100644 --- a/example/logical.cpp +++ b/example/logical.cpp @@ -10,7 +10,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include #include -#include +#include #include #include diff --git a/example/map.cpp b/example/map.cpp index 4f3d004f4..b6770de5f 100644 --- a/example/map.cpp +++ b/example/map.cpp @@ -6,7 +6,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include -#include +#include #include #include #include diff --git a/example/maybe.cpp b/example/maybe.cpp index eccfea20f..518d982c1 100644 --- a/example/maybe.cpp +++ b/example/maybe.cpp @@ -7,7 +7,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include #include -#include +#include #include #include using namespace boost::hana; diff --git a/example/monoid.cpp b/example/monoid.cpp index 4c491855e..ebbf9cb1c 100644 --- a/example/monoid.cpp +++ b/example/monoid.cpp @@ -5,7 +5,7 @@ Distributed under the Boost Software License, Version 1.0. */ #include -#include +#include using namespace boost::hana; @@ -14,7 +14,7 @@ int main() { { //! [zero] -BOOST_HANA_CONSTANT_CHECK(zero>() == int_<0>); +BOOST_HANA_CONSTANT_CHECK(zero>() == int_<0>); BOOST_HANA_CONSTEXPR_CHECK(zero() == 0l); //! [zero] diff --git a/example/orderable.cpp b/example/orderable.cpp index e8c3e7344..a9fbb667d 100644 --- a/example/orderable.cpp +++ b/example/orderable.cpp @@ -6,7 +6,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include -#include +#include #include #include using namespace boost::hana; diff --git a/example/range.cpp b/example/range.cpp index 12a7fd680..f7cbfe637 100644 --- a/example/range.cpp +++ b/example/range.cpp @@ -6,7 +6,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include -#include +#include #include #include #include diff --git a/example/ring.cpp b/example/ring.cpp index 9af6a6691..dc2f925ce 100644 --- a/example/ring.cpp +++ b/example/ring.cpp @@ -5,7 +5,7 @@ Distributed under the Boost Software License, Version 1.0. */ #include -#include +#include using namespace boost::hana; @@ -22,7 +22,7 @@ BOOST_HANA_CONSTEXPR_CHECK(mult(4, 2) == 8); }{ //! [one] -BOOST_HANA_CONSTANT_CHECK(one>() == int_<1>); +BOOST_HANA_CONSTANT_CHECK(one>() == int_<1>); BOOST_HANA_CONSTEXPR_CHECK(one() == 1l); //! [one] diff --git a/example/searchable.cpp b/example/searchable.cpp index f5b1fe89f..14e01396a 100644 --- a/example/searchable.cpp +++ b/example/searchable.cpp @@ -9,7 +9,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include #include -#include +#include #include #include #include diff --git a/example/set.cpp b/example/set.cpp index 6da5e9edc..96b963ef2 100644 --- a/example/set.cpp +++ b/example/set.cpp @@ -6,7 +6,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include -#include +#include #include #include #include diff --git a/example/string.cpp b/example/string.cpp index a92bddf88..e0c29e80a 100644 --- a/example/string.cpp +++ b/example/string.cpp @@ -7,7 +7,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include #include -#include +#include #include #include using namespace boost::hana; diff --git a/example/traversable.cpp b/example/traversable.cpp index bc7a23d45..199c9158f 100644 --- a/example/traversable.cpp +++ b/example/traversable.cpp @@ -5,7 +5,7 @@ Distributed under the Boost Software License, Version 1.0. */ #include -#include +#include #include #include using namespace boost::hana; diff --git a/example/tutorial/basic_concepts/constant/integral.cpp b/example/tutorial/basic_concepts/constant/integral.cpp index 9805ebb3a..cc4e6979f 100644 --- a/example/tutorial/basic_concepts/constant/integral.cpp +++ b/example/tutorial/basic_concepts/constant/integral.cpp @@ -5,15 +5,15 @@ Distributed under the Boost Software License, Version 1.0. */ #include -#include +#include #include using namespace boost::hana; //! [integral_create] -auto two = integral; -auto yes = integral; +auto two = integral_constant; +auto yes = integral_constant; //! [integral_create] //! [integral_api] @@ -47,7 +47,7 @@ BOOST_HANA_CONSTANT_CHECK(-1234_c == llong<-1234>); } //! [integral_operators] -BOOST_HANA_CONSTANT_CHECK(int_<1> == integral); +BOOST_HANA_CONSTANT_CHECK(int_<1> == integral_constant); BOOST_HANA_CONSTANT_CHECK(int_<1> + long_<2> == long_<3>); BOOST_HANA_CONSTANT_CHECK(!(bool_ && bool_)); //! [integral_operators] diff --git a/example/type.cpp b/example/type.cpp index 948d45233..e744fd787 100644 --- a/example/type.cpp +++ b/example/type.cpp @@ -8,7 +8,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include #include -#include +#include #include #include diff --git a/include/boost/hana.hpp b/include/boost/hana.hpp index c8f15e208..436309a05 100644 --- a/include/boost/hana.hpp +++ b/include/boost/hana.hpp @@ -54,7 +54,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include #include -#include +#include #include #include #include @@ -462,7 +462,7 @@ variable template: constexpr unspecified integral{}; @endcode -where the type of `integral<...>`, while being unspecified, actually looks a +where the type of `integral_constant<...>`, while being unspecified, actually looks a lot like a `std::integral_constant`. Indeed, an `Integral` is guaranteed to have the same members as an equivalent `std::integral_constant`, so they can be used as such @@ -481,7 +481,7 @@ Additionally, `Integral`s can be created with the help of [user-defined literals However, this syntax only allows creating `Integral`s with an underlying value of type `long long`. Another feature of `Integral`s is that they overload -common operators so that `integral<...>`s can be used with an intuitive +common operators so that `integral_constant<...>`s can be used with an intuitive syntax: @snippet example/tutorial/basic_concepts/constant/integral.cpp integral_operators @@ -490,7 +490,7 @@ It is important to realize that these operators return `Integral`s, not normal values of an integral type. Specifically, for an operator `@`, @code - integral @ integral == integral + integral_constant @ integral_constant == integral_constant @endcode This is very important because it allows all the information that's known at diff --git a/include/boost/hana/constant.hpp b/include/boost/hana/constant.hpp index f03f807e3..9147aa2ea 100644 --- a/include/boost/hana/constant.hpp +++ b/include/boost/hana/constant.hpp @@ -53,7 +53,9 @@ namespace boost { namespace hana { //! @todo //! This is an awful hack to avoid having //! @code - //! common, Integral> == CanonicalConstant + //! common, IntegralConstant> + //! == + //! CanonicalConstant //! @endcode template struct which { diff --git a/include/boost/hana/foldable.hpp b/include/boost/hana/foldable.hpp index 82b334651..007c243e2 100644 --- a/include/boost/hana/foldable.hpp +++ b/include/boost/hana/foldable.hpp @@ -27,7 +27,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include #include -#include +#include #include #include #include @@ -184,14 +184,14 @@ namespace boost { namespace hana { //! @todo Make it possible to specify the Monoid that's used? template static constexpr decltype(auto) sum_impl(Xs&& xs) { - using M = Integral; + using M = IntegralConstant; return foldl(detail::std::forward(xs), zero(), plus); } //! @todo Make it possible to specify the Ring that's used? template static constexpr decltype(auto) product_impl(Xs&& xs) { - using R = Integral; + using R = IntegralConstant; return foldl(detail::std::forward(xs), one(), mult); } diff --git a/include/boost/hana/fwd/integer_list.hpp b/include/boost/hana/fwd/integer_list.hpp index 574d5f705..68025c277 100644 --- a/include/boost/hana/fwd/integer_list.hpp +++ b/include/boost/hana/fwd/integer_list.hpp @@ -42,7 +42,7 @@ namespace boost { namespace hana { //! Creates a list containing the given `Integral`s. //! @relates IntegerList //! - //! This is functionally equivalent to `tuple(integral...)`. + //! This is functionally equivalent to `tuple(integral_constant...)`. //! //! ### Example //! @snippet example/integer_list/integer_list.cpp main diff --git a/include/boost/hana/fwd/integral.hpp b/include/boost/hana/fwd/integral.hpp deleted file mode 100644 index d567ec6d8..000000000 --- a/include/boost/hana/fwd/integral.hpp +++ /dev/null @@ -1,261 +0,0 @@ -/*! -@file -Forward declares `boost::hana::Integral`. - -@copyright Louis Dionne 2014 -Distributed under the Boost Software License, Version 1.0. -(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) - */ - -#ifndef BOOST_HANA_FWD_INTEGRAL_HPP -#define BOOST_HANA_FWD_INTEGRAL_HPP - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -namespace boost { namespace hana { - //! @ingroup group-datatypes - //! Represents a compile-time value of an integral type. - //! - //! `Integral`s are guaranteed to have the same members and capabilities - //! as the corresponding `std::integral_constant`. For example, `Integral`s - //! are `constexpr`-convertible to their underlying type, they have a - //! nested static constant named `value` holding their underlying value, - //! and so on. - //! - //! `Integral`s also have a member function named `times`, which allows a - //! nullary function to be invoked `n` times. - //! - //! For convenience, common operators are overloaded to return the result - //! of the corresponding operator as an `integral<...>`. - //! - //! ## Overloaded operators - //! - Arithmetic: binary `+`, binary `-`, `/`, `*`, `%`, unary `+`, - //! unary `-` - //! - Bitwise: `~`, `&`, `|`, `^`, `<<`, `>>` - //! - Comparison: `==`, `!=`, `<`, `<=`, `>`, `>=` - //! - Logical: `||`, `&&`, `!` - //! - Member access: `*` (dereference) - //! - //! ## Example - //! @snippet example/integral.cpp operators - //! - //! ## Instance of - //! `Comparable`, `Orderable`, `Constant`, `Logical`, `Monoid`, `Group`, - //! `Ring`, `IntegralDomain`, and `IntegralConstant`. - //! - //! @todo - //! Implicit conversions to the underlying integral type can be problematic: - //! @code - //! constexpr auto odd = [](auto x) { - //! return x % int_<2>; - //! }; - //! - //! if_(odd(int_<1>), something_of_type_A, something_of_type_B) - //! @endcode - //! This will fail because `odd(int_<1>)` has type `Int<1 % 2>`, which is - //! convertible to `bool` but not to `Bool<...>`. Because of this, the - //! runtime `if_` is used and compilation fails. - //! - //! @todo - //! `times` should be a shortcut to some type class method. Specifically, - //! anything that can be incremented, decremented and compared to some - //! "zero" value can implement a `times` method with the same semantics. - template - struct Integral { - struct hana { - struct enabled_operators - : Comparable, Orderable, - Logical, - Monoid, Group, Ring, IntegralDomain - { }; - }; - using value_type = T; - }; - - namespace integral_detail { - template - struct integral : operators::enable_adl { - using type = integral; - using value_type = T; - static constexpr value_type value = v; - constexpr operator value_type() const noexcept { return value; } - constexpr value_type operator()() const noexcept { return value; } - - struct hana { - using datatype = Integral< - typename boost::hana::datatype::type - >; - }; - - template - constexpr void times(F&& f) const { - detail::n_times(detail::std::forward(f)); - } - }; - -#define BOOST_HANA_INTEGRAL_BINARY_OP(op) \ - template \ - constexpr integral \ - operator op(integral, integral) \ - { return {}; } \ -/**/ - -#define BOOST_HANA_INTEGRAL_UNARY_OP(op) \ - template \ - constexpr integral \ - operator op(integral) \ - { return {}; } \ -/**/ - - // Arithmetic - BOOST_HANA_INTEGRAL_UNARY_OP(+) - - // Bitwise - BOOST_HANA_INTEGRAL_UNARY_OP(~) - BOOST_HANA_INTEGRAL_BINARY_OP(&) - BOOST_HANA_INTEGRAL_BINARY_OP(|) - BOOST_HANA_INTEGRAL_BINARY_OP(^) - BOOST_HANA_INTEGRAL_BINARY_OP(<<) - BOOST_HANA_INTEGRAL_BINARY_OP(>>) - -#undef BOOST_HANA_INTEGRAL_UNARY_OP -#undef BOOST_HANA_INTEGRAL_BINARY_OP - } // end namespace integral_detail - - //! A compile-time integral value of the given type and value. - //! @relates Integral - //! - //! @note - //! For any `const-volatility` specifier `cv`, `integral` is - //! always the same as `integral`. - //! - //! @internal - //! ### Rationale for striping cv-specifiers - //! In the following idiom, - //! @code - //! integral - //! @endcode - //! if `Trait::value` is declared as `static const T value = ...;`, then - //! `decltype(Trait::value)` is `T const` instead of `T`. This causes - //! unintuitive behavior in some cases. For example, with a definition - //! of `trait::is_floating_point` using the above idiom, - //! @code - //! static_assert( - //! decltype_(trait::is_floating_point(type)) == - //! decltype_(false_) - //! , ""); - //! @endcode - //! will fail, but the following will succeed - //! @code - //! static_assert( - //! decltype_(trait::is_floating_point(type)) == - //! decltype_(integral) - //! , ""); - //! @endcode - //! Since there does not seem to be a lot of use cases for keeping - //! cv-qualifiers in the integral type, we just remove them. - //! - //! @todo - //! Do we want `char_<1> + char_<2> == char_<3>` or - //! `char_<1> + char_<2> == int_<3>`? - //! - //! @todo - //! Consider specifying the type of `integral<...>` to allow overloading - //! on its type. Not sure yet whether that's desirable or not. - template - constexpr integral_detail::integral< - typename detail::std::remove_cv::type, v - > integral{}; - - //! @relates Integral - template - constexpr auto char_ = decltype(integral){}; - - //! @relates Integral - template - constexpr auto short_ = decltype(integral){}; - - //! @relates Integral - template - constexpr auto ushort = decltype(integral){}; - - //! @relates Integral - template - constexpr auto int_ = decltype(integral){}; - - //! @relates Integral - template - constexpr auto uint = decltype(integral){}; - - //! @relates Integral - template - constexpr auto long_ = decltype(integral){}; - - //! @relates Integral - template - constexpr auto ulong = decltype(integral){}; - - //! @relates Integral - template - constexpr auto llong = decltype(integral){}; - - //! @relates Integral - template - constexpr auto ullong = decltype(integral){}; - - //! @relates Integral - template - constexpr auto size_t = decltype(integral){}; - - namespace integral_detail { - constexpr int to_int(char c) - { return static_cast(c) - 48; } - - template - constexpr long long parse(const char (&arr)[N]) { - long long number = 0, base = 1; - for (decltype(N) i = 0; i < N; ++i) { - number += to_int(arr[N - 1 - i]) * base; - base *= 10; - } - return number; - } - } - - namespace literals { - //! Creates an `Integral` from a literal. - //! @relates boost::hana::Integral - //! - //! The literal is parsed at compile-time and the result is returned - //! as an `llong<...>`. - //! - //! @note - //! We use `llong<...>` instead of `ullong<...>` because using an - //! unsigned type leads to unexpected behavior when doing stuff like - //! `-1_c`. If we used an unsigned type, `-1_c` would be something - //! like `ullong<-1>` which is actually `ullong`. - //! - //! ### Example - //! @snippet example/integral.cpp literals - //! - //! @todo Add support for stuff like `0x1234_c`. - template - constexpr auto operator"" _c() - { return llong({c...})>; } - } -}} // end namespace boost::hana - -#endif // !BOOST_HANA_FWD_INTEGRAL_HPP diff --git a/include/boost/hana/fwd/integral_constant.hpp b/include/boost/hana/fwd/integral_constant.hpp new file mode 100644 index 000000000..232707a58 --- /dev/null +++ b/include/boost/hana/fwd/integral_constant.hpp @@ -0,0 +1,247 @@ +/*! +@file +Forward declares `boost::hana::IntegralConstant`. + +@copyright Louis Dionne 2014 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + */ + +#ifndef BOOST_HANA_FWD_INTEGRAL_CONSTANT_HPP +#define BOOST_HANA_FWD_INTEGRAL_CONSTANT_HPP + +#include + + +namespace boost { namespace hana { + //! @ingroup group-datatypes + //! Represents a compile-time value of an integral type. + //! + //! An `IntegralConstant` is an object that represents a compile-time + //! integral value. In fact, as the name suggests, an `IntegralConstant` + //! is basically equivalent to a `std::integral_constant`, except that + //! Hana's `IntegralConstant`s also provide other goodies to make them + //! easier to use. In particular, `IntegralConstant`s are guaranteed to + //! have the same members and capabilities as `std::integral_constant`s. + //! For example, `IntegralConstant`s are `constexpr`-convertible to their + //! underlying type, they have a nested static constant named `value` + //! holding their underlying value, and so on. + //! + //! > #### Rationale for not sticking with `std::integral_constant` + //! > First, we wanted to have arithmetic operators and other goodies, + //! > which is much harder if we don't use our own objects. Second, using + //! > `std::integral_constant` requires including the whole `` + //! > header, which is about half the size of the whole Hana library. + //! + //! + //! As outlined above, the interface of an `IntegralConstant` is a + //! superset of what's provided by `std::integral_constant`. The sections + //! below explain those additions. + //! + //! + //! Arithmetic operators + //! -------------------- + //! `IntegralConstant` provides arithmetic operators that return + //! `IntegralConstant`s, so compile-time arithmetic can be done easily: + //! @snippet example/integral_constant.cpp operators + //! + //! All those operators work pretty much in the same way. Simply put, + //! @code + //! integral_constant op integral_constant == integral_constant + //! @endcode + //! + //! The full range of provided operators is + //! - Arithmetic: binary `+`, binary `-`, `/`, `*`, `%`, unary `+`, unary `-` + //! - Bitwise: `~`, `&`, `|`, `^`, `<<`, `>>` + //! - Comparison: `==`, `!=`, `<`, `<=`, `>`, `>=` + //! - Logical: `||`, `&&`, `!` + //! - Member access: `*` (dereference) + //! + //! + //! `times` function + //! ---------------- + //! `IntegralConstant`s also have a static member function object named + //! `times`, which allows a nullary function to be invoked `n` times: + //! @code + //! int_<3>.times(f) + //! @endcode + //! should be expanded by any decent compiler to + //! @code + //! f(); f(); f(); + //! @endcode + //! + //! This can be useful in several contexts, e.g. for loop unrolling: + //! @snippet example/integral_constant.cpp times_loop_unrolling + //! + //! Note that `times` is really a static function object. Since static + //! members can be accessed using both the `.` and the `::` syntax, Hana + //! takes advantage of this (loophole?) to make `times` accessible both + //! from the type of an `IntegralConstant` object and from an object + //! itself: + //! @snippet example/integral_constant.cpp as_static_member + //! + //! Also, since `times` is a function object instead of an + //! overloaded function, it does not need to be called right away, which + //! can be useful in conjunction with some higher-order algorithms: + //! @snippet example/integral_constant.cpp times_higher_order + //! + //! Sometimes, it is also useful to know the index we're at inside the + //! function. This is also possible: + //! @snippet example/integral_constant.cpp times_with_index_runtime + //! + //! Remember that `times` is a _function object_, and hence it can have + //! subobjects. `with_index` is then just a function object nested inside + //! `times`, which allows for this nice little interface. Also note that + //! the indices passed to the function are `IntegralConstant`s; they are + //! known at compile-time. Hence, we can do compile-time stuff with them, + //! like indexing inside a tuple: + //! @snippet example/integral_constant.cpp times_with_index_compile_time + //! + //! + //! Construction with user-defined literals + //! --------------------------------------- + //! `IntegralConstant`s of type `long long` can be created with the + //! `_c` user-defined literal, which is contained in the `literals` + //! namespace: + //! @snippet example/integral_constant.cpp literals + //! + //! + //! Modeled concepts + //! ---------------- + //! 1. `Constant`\n + //! An `IntegralConstant` is a model of the `Constant` concept in the most + //! obvious way possible. Specifically, + //! @code + //! constexpr auto c = integral_constant; + //! static_assert(value2() == 10, ""); + //! @endcode + //! + //! 2. `Comparable`, `Orderable`, `Logical`, `Monoid`, `Group`, `Ring`, + //! and `IntegralDomain` (operators provided)\n + //! Those models are exactly those provided for `Constant`s, which are + //! documented in their respective concepts. + //! + //! + //! @todo + //! `times` should be a shortcut to some tag-dispatched method. Specifically, + //! anything that can be incremented, decremented and compared to some + //! "zero" value can implement a `times` method with the same semantics. + //! + //! @todo + //! Implicit conversions to the underlying integral type can be problematic: + //! @code + //! constexpr auto odd = [](auto x) { + //! return x % int_<2>; + //! }; + //! + //! if_(odd(int_<1>), something_of_type_A, something_of_type_B) + //! @endcode + //! This will fail because `odd(int_<1>)` has type `Int<1 % 2>`, which is + //! convertible to `bool` but not to `Bool<...>`. Because of this, the + //! runtime `if_` is used and compilation fails. + template + struct IntegralConstant { + using value_type = T; + }; + + //! Creates an `IntegralConstant` holding the given compile-time value. + //! @relates IntegralConstant + //! + //! Specifically, `integral_constant + char_<2> == char_<3>` or + //! `char_<1> + char_<2> == int_<3>`? + //! - Consider specifying the type of `integral_constant<...>` to allow + //! overloading on its type. Not sure yet whether that's desirable or not. +#ifdef BOOST_HANA_DOXYGEN_INVOKED + template + constexpr unspecified-type integral_constant{}; +#else + template + struct _integral_constant; + + template + constexpr _integral_constant integral_constant{}; +#endif + + //! @relates IntegralConstant + template + constexpr auto char_ = integral_constant; + + //! @relates IntegralConstant + template + constexpr auto short_ = integral_constant; + + //! @relates IntegralConstant + template + constexpr auto ushort = integral_constant; + + //! @relates IntegralConstant + template + constexpr auto int_ = integral_constant; + + //! @relates IntegralConstant + template + constexpr auto uint = integral_constant; + + //! @relates IntegralConstant + template + constexpr auto long_ = integral_constant; + + //! @relates IntegralConstant + template + constexpr auto ulong = integral_constant; + + //! @relates IntegralConstant + template + constexpr auto llong = integral_constant; + + //! @relates IntegralConstant + template + constexpr auto ullong = integral_constant; + + //! @relates IntegralConstant + template + constexpr auto size_t = integral_constant; + + namespace literals { + //! Creates an `IntegralConstant` from a literal. + //! @relates boost::hana::IntegralConstant + //! + //! The literal is parsed at compile-time and the result is returned + //! as an `llong<...>`. + //! + //! @note + //! We use `llong<...>` instead of `ullong<...>` because using an + //! unsigned type leads to unexpected behavior when doing stuff like + //! `-1_c`. If we used an unsigned type, `-1_c` would be something + //! like `ullong<-1>` which is actually `ullong`. + //! + //! + //! Example + //! ------- + //! @snippet example/integral_constant.cpp literals + //! + //! @todo Add support for stuff like `0x1234_c`. + template + constexpr auto operator"" _c(); + } +}} // end namespace boost::hana + +#endif // !BOOST_HANA_FWD_INTEGRAL_CONSTANT_HPP diff --git a/include/boost/hana/fwd/iterable.hpp b/include/boost/hana/fwd/iterable.hpp index 712981dd4..16c0345ef 100644 --- a/include/boost/hana/fwd/iterable.hpp +++ b/include/boost/hana/fwd/iterable.hpp @@ -15,7 +15,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include #include -#include +#include namespace boost { namespace hana { diff --git a/include/boost/hana/fwd/list.hpp b/include/boost/hana/fwd/list.hpp index 22ddc261e..b9faa2118 100644 --- a/include/boost/hana/fwd/list.hpp +++ b/include/boost/hana/fwd/list.hpp @@ -19,7 +19,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include #include -#include +#include namespace boost { namespace hana { diff --git a/include/boost/hana/fwd/range.hpp b/include/boost/hana/fwd/range.hpp index 59d7fd98b..6d8d7e7b9 100644 --- a/include/boost/hana/fwd/range.hpp +++ b/include/boost/hana/fwd/range.hpp @@ -11,7 +11,7 @@ Distributed under the Boost Software License, Version 1.0. #define BOOST_HANA_FWD_RANGE_HPP #include -#include +#include namespace boost { namespace hana { @@ -91,7 +91,8 @@ namespace boost { namespace hana { //! This shorthand is provided for convenience only and it is equivalent //! to `range`. Specifically, `range_c` is such that //! @code - //! range_c == range(integral, integral) + //! range_c == range(integral_constant, + //! integral_constant) //! @endcode //! //! @@ -109,7 +110,8 @@ namespace boost { namespace hana { //! ------- //! @snippet example/range.cpp range_c template - constexpr auto range_c = range(integral, integral); + constexpr auto range_c = range(integral_constant, + integral_constant); }} // end namespace boost::hana #endif // !BOOST_HANA_FWD_RANGE_HPP diff --git a/include/boost/hana/fwd/ring.hpp b/include/boost/hana/fwd/ring.hpp index b1ed24fc7..37b41a87b 100644 --- a/include/boost/hana/fwd/ring.hpp +++ b/include/boost/hana/fwd/ring.hpp @@ -198,7 +198,7 @@ namespace boost { namespace hana { //! A `Ring` element that is elevated to its `n`th power. //! //! @param n - //! An `IntegralConstant` representing the power to which `r` is elevated. + //! An integral `Constant` representing the power to which `r` is elevated. //! //! //! @note diff --git a/include/boost/hana/fwd/tuple.hpp b/include/boost/hana/fwd/tuple.hpp index 2a4a2b9e4..0f1bf61de 100644 --- a/include/boost/hana/fwd/tuple.hpp +++ b/include/boost/hana/fwd/tuple.hpp @@ -16,7 +16,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include #include -#include +#include #include @@ -63,7 +63,7 @@ namespace boost { namespace hana { constexpr auto tuple_t = tuple(type...); template - constexpr auto tuple_c = tuple(integral...); + constexpr auto tuple_c = tuple(integral_constant...); }} // end namespace boost::hana #endif // !BOOST_HANA_FWD_TUPLE_HPP diff --git a/include/boost/hana/fwd/type.hpp b/include/boost/hana/fwd/type.hpp index 4773f10a3..b4ce24ebb 100644 --- a/include/boost/hana/fwd/type.hpp +++ b/include/boost/hana/fwd/type.hpp @@ -410,7 +410,7 @@ namespace boost { namespace hana { //! Specifically, `trait(t...)` is equivalent to `template_(t...)()`. //! The principal use case for `trait` is to transform metafunctions //! inheriting from a meaningful base like `std::integral_constant` - //! into functions returning e.g. an `Integral`. + //! into functions returning e.g. an `IntegralConstant`. //! //! The word `trait` is used because a name was needed and the principal //! use case involves metafunctions from the standard that we also call diff --git a/include/boost/hana/integer_list.hpp b/include/boost/hana/integer_list.hpp index 949742b8e..4cb098f94 100644 --- a/include/boost/hana/integer_list.hpp +++ b/include/boost/hana/integer_list.hpp @@ -13,7 +13,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include -#include +#include // instances #include @@ -23,14 +23,14 @@ Distributed under the Boost Software License, Version 1.0. namespace boost { namespace hana { //! Instance of `Iterable` for `IntegerList`s. //! - //! The head of `integer_list` is `integral`, its tail + //! The head of `integer_list` is `integral_constant`, its tail //! is `integer_list` and an integer list is empty if and only //! if it contains no integers at all. template <> struct Iterable::instance : Iterable::mcd { template static constexpr auto head_impl(ilist_detail::integer_list) { - return integral; + return integral_constant; } template diff --git a/include/boost/hana/integral.hpp b/include/boost/hana/integral.hpp deleted file mode 100644 index eaae467d2..000000000 --- a/include/boost/hana/integral.hpp +++ /dev/null @@ -1,67 +0,0 @@ -/*! -@file -Defines `boost::hana::Integral`. - -@copyright Louis Dionne 2014 -Distributed under the Boost Software License, Version 1.0. -(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) - */ - -#ifndef BOOST_HANA_INTEGRAL_HPP -#define BOOST_HANA_INTEGRAL_HPP - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -namespace boost { namespace hana { - ////////////////////////////////////////////////////////////////////////// - // Constant - ////////////////////////////////////////////////////////////////////////// - template - struct models)> - : detail::std::true_type - { }; - - template - struct value_impl> { - template - static constexpr auto apply(C const&) - { return C::value; } - }; - - template - struct to_impl, C, when< - models{} && - detail::std::is_integral{} - >> - : embedding{}> - { - static_assert(detail::std::is_integral{}, - "trying to convert a Constant to an Integral of a non-integral " - "type; boost::hana::Integral may only hold integral types"); - - template - static constexpr auto apply(X x) { - constexpr auto v = hana::value(x); - return integral(v)>; - } - }; -}} // end namespace boost::hana - -#endif // !BOOST_HANA_INTEGRAL_HPP diff --git a/include/boost/hana/integral_constant.hpp b/include/boost/hana/integral_constant.hpp new file mode 100644 index 000000000..6c899a026 --- /dev/null +++ b/include/boost/hana/integral_constant.hpp @@ -0,0 +1,197 @@ +/*! +@file +Defines `boost::hana::IntegralConstant`. + +@copyright Louis Dionne 2014 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + */ + +#ifndef BOOST_HANA_INTEGRAL_CONSTANT_HPP +#define BOOST_HANA_INTEGRAL_CONSTANT_HPP + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// provided models +#include +#include +#include +#include +#include +#include +#include + + +namespace boost { namespace hana { + ////////////////////////////////////////////////////////////////////////// + // integral_constant + ////////////////////////////////////////////////////////////////////////// + namespace ic_detail { + template > + struct go; + + template + struct go> { + using swallow = T[]; + + template + static constexpr void with_index(F&& f) + { (void)swallow{T{}, ((void)f(integral_constant), i)...}; } + + template + static constexpr void without_index(F&& f) + { (void)swallow{T{}, ((void)f(), i)...}; } + }; + + template + struct _with_index { + template + constexpr void operator()(F&& f) const + { go::with_index(detail::std::forward(f)); } + }; + + template + struct _times { + static constexpr _with_index with_index{}; + + template + constexpr void operator()(F&& f) const + { go::without_index(detail::std::forward(f)); } + }; + + // avoid link-time error + template + constexpr _with_index _times::with_index; + } + + template + struct _integral_constant : operators::enable_adl { + // std::integral_constant interface + using type = _integral_constant; + using value_type = T; + static constexpr value_type value = v; + constexpr operator value_type() const noexcept { return value; } + constexpr value_type operator()() const noexcept { return value; } + + // times + static constexpr ic_detail::_times times{}; + }; + + // avoid link-time error + template + constexpr ic_detail::_times _integral_constant::times; + + template + struct datatype<_integral_constant> { + using type = IntegralConstant; + }; + + ////////////////////////////////////////////////////////////////////////// + // Operators (most of them are provided by the concepts) + ////////////////////////////////////////////////////////////////////////// + template + struct enabled_operators> + : Comparable, Orderable + , Logical + , Monoid, Group, Ring, IntegralDomain + { }; + +#define BOOST_HANA_INTEGRAL_CONSTANT_BINARY_OP(op) \ + template \ + constexpr _integral_constant \ + operator op(_integral_constant, _integral_constant) \ + { return {}; } \ + /**/ + +#define BOOST_HANA_INTEGRAL_CONSTANT_UNARY_OP(op) \ + template \ + constexpr _integral_constant \ + operator op(_integral_constant) \ + { return {}; } \ + /**/ + + // Arithmetic + BOOST_HANA_INTEGRAL_CONSTANT_UNARY_OP(+) + + // Bitwise + BOOST_HANA_INTEGRAL_CONSTANT_UNARY_OP(~) + BOOST_HANA_INTEGRAL_CONSTANT_BINARY_OP(&) + BOOST_HANA_INTEGRAL_CONSTANT_BINARY_OP(|) + BOOST_HANA_INTEGRAL_CONSTANT_BINARY_OP(^) + BOOST_HANA_INTEGRAL_CONSTANT_BINARY_OP(<<) + BOOST_HANA_INTEGRAL_CONSTANT_BINARY_OP(>>) + +#undef BOOST_HANA_INTEGRAL_CONSTANT_UNARY_OP +#undef BOOST_HANA_INTEGRAL_CONSTANT_BINARY_OP + + + ////////////////////////////////////////////////////////////////////////// + // User-defined literal + ////////////////////////////////////////////////////////////////////////// + namespace ic_detail { + constexpr int to_int(char c) + { return static_cast(c) - 48; } + + template + constexpr long long parse(const char (&arr)[N]) { + long long number = 0, base = 1; + for (detail::std::size_t i = 0; i < N; ++i) { + number += to_int(arr[N - 1 - i]) * base; + base *= 10; + } + return number; + } + } + + namespace literals { + template + constexpr auto operator"" _c() + { return llong({c...})>; } + } + + ////////////////////////////////////////////////////////////////////////// + // Model of Constant + ////////////////////////////////////////////////////////////////////////// + template + struct models)> + : detail::std::true_type + { }; + + template + struct value_impl> { + template + static constexpr auto apply(C const&) + { return C::value; } + }; + + template + struct to_impl, C, when< + models{} && + detail::std::is_integral{} + >> + : embedding{}> + { + static_assert(detail::std::is_integral{}, + "trying to convert a Constant to an IntegralConstant of a non-integral " + "type; boost::hana::IntegralConstant may only hold integral types"); + + template + static constexpr auto apply(X x) { + constexpr auto v = hana::value(x); + return integral_constant(v)>; + } + }; +}} // end namespace boost::hana + +#endif // !BOOST_HANA_INTEGRAL_CONSTANT_HPP diff --git a/include/boost/hana/list.hpp b/include/boost/hana/list.hpp index 126f63f4b..15b1ac5f7 100644 --- a/include/boost/hana/list.hpp +++ b/include/boost/hana/list.hpp @@ -30,7 +30,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include #include -#include +#include #include #include #include diff --git a/include/boost/hana/range.hpp b/include/boost/hana/range.hpp index 8d9246b57..16cce589a 100644 --- a/include/boost/hana/range.hpp +++ b/include/boost/hana/range.hpp @@ -26,7 +26,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include #include -#include // required by fwd decl +#include // required by fwd decl #include #include #include @@ -115,7 +115,7 @@ namespace boost { namespace hana { unpack_helper(R r, F&& f, detail::std::integer_sequence) { using U = typename R::underlying; constexpr auto from = hana::value(r.from); - return detail::std::forward(f)(to(integral)...); + return detail::std::forward(f)(to(integral_constant)...); } template @@ -184,7 +184,7 @@ namespace boost { namespace hana { constexpr auto from = hana::value(r.from); constexpr auto to = hana::value(r.to); constexpr auto s = from == to ? 0 : sum_helper(from, to-1); - return hana::to(integral); + return hana::to(integral_constant); } }; @@ -209,7 +209,7 @@ namespace boost { namespace hana { constexpr auto from = hana::value(r.from); constexpr auto to = hana::value(r.to); constexpr auto s = product_helper(from, to); - return hana::to(integral); + return hana::to(integral_constant); } }; diff --git a/include/boost/hana/sandbox/lambda_tuple.hpp b/include/boost/hana/sandbox/lambda_tuple.hpp index fb8e59a89..0bc9865a8 100644 --- a/include/boost/hana/sandbox/lambda_tuple.hpp +++ b/include/boost/hana/sandbox/lambda_tuple.hpp @@ -79,7 +79,7 @@ namespace boost { namespace hana { namespace sandbox { #include #include #include -#include +#include #include #include diff --git a/include/boost/hana/string.hpp b/include/boost/hana/string.hpp index 22d0ff0e5..6ad350d55 100644 --- a/include/boost/hana/string.hpp +++ b/include/boost/hana/string.hpp @@ -24,7 +24,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include #include -#include +#include #include #include #include diff --git a/include/boost/hana/tuple.hpp b/include/boost/hana/tuple.hpp index 442af3d30..3512558e2 100644 --- a/include/boost/hana/tuple.hpp +++ b/include/boost/hana/tuple.hpp @@ -26,7 +26,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include #include -#include // size_t +#include // size_t // instances #include diff --git a/include/boost/hana/type.hpp b/include/boost/hana/type.hpp index ca8f4e0cc..21e646985 100644 --- a/include/boost/hana/type.hpp +++ b/include/boost/hana/type.hpp @@ -16,7 +16,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include #include -#include +#include namespace boost { namespace hana { diff --git a/test/bugs/integral_constexpr_init.cpp b/test/bugs/integral_constexpr_init.cpp index 876b18e01..b7f739fdf 100644 --- a/test/bugs/integral_constexpr_init.cpp +++ b/test/bugs/integral_constexpr_init.cpp @@ -5,7 +5,7 @@ Distributed under the Boost Software License, Version 1.0. */ #include -#include +#include using namespace boost::hana; @@ -13,16 +13,16 @@ using namespace boost::hana; When we use `int_<...>` in a template, Clang 3.5 says: -------------------------------- -include/boost/hana/integral.hpp:80:20: error: constexpr variable 'int_<1>' must be initialized by a constant expression +include/boost/hana/integral_constant.hpp:80:20: error: constexpr variable 'int_<1>' must be initialized by a constant expression constexpr auto int_ = integral; ^ ~~~~~~~~~~~~~~~~ test/integral/constexpr_bug.cpp:41:37: note: in instantiation of variable template specialization 'boost::hana::int_' requested here constexpr auto check_int() { return int_<1>; } ^ -include/boost/hana/integral.hpp:80:27: note: subexpression not valid in a constant expression +include/boost/hana/integral_constant.hpp:80:27: note: subexpression not valid in a constant expression constexpr auto int_ = integral; ^ -include/boost/hana/integral.hpp:80:27: note: in call to 'integral_type(integral)' +include/boost/hana/integral_constant.hpp:80:27: note: in call to 'integral_type(integral)' -------------------------------- if we define int_ & friends like diff --git a/test/bugs/integral_strip_cv.cpp b/test/bugs/integral_strip_cv.cpp deleted file mode 100644 index 48338c0c3..000000000 --- a/test/bugs/integral_strip_cv.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/* -@copyright Louis Dionne 2014 -Distributed under the Boost Software License, Version 1.0. -(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) - */ - -#include - -#include -#include -using namespace boost::hana; - - -template -constexpr void test_for() { - BOOST_HANA_CONSTANT_CHECK(equal( - decltype_(integral), - decltype_(integral) - )); - BOOST_HANA_CONSTANT_CHECK(equal( - decltype_(integral), - decltype_(integral) - )); - BOOST_HANA_CONSTANT_CHECK(equal( - decltype_(integral), - decltype_(integral) - )); -} - -int main() { - test_for(); - test_for(); - test_for(); - test_for(); - test_for(); -} diff --git a/test/bugs/type_usability_in_tuple.cpp b/test/bugs/type_usability_in_tuple.cpp index 7a1a128ac..37a0ce7a6 100644 --- a/test/bugs/type_usability_in_tuple.cpp +++ b/test/bugs/type_usability_in_tuple.cpp @@ -4,7 +4,7 @@ Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) */ -#include +#include #include #include diff --git a/test/ext/boost/mpl/integral_c.cpp b/test/ext/boost/mpl/integral_c.cpp index 4f1799cc1..05d0e6f08 100644 --- a/test/ext/boost/mpl/integral_c.cpp +++ b/test/ext/boost/mpl/integral_c.cpp @@ -8,7 +8,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include -#include +#include #include #include diff --git a/test/ext/std/integral_constant.cpp b/test/ext/std/integral_constant.cpp index 5e5955213..d10fd7613 100644 --- a/test/ext/std/integral_constant.cpp +++ b/test/ext/std/integral_constant.cpp @@ -7,7 +7,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include -#include +#include #include #include diff --git a/test/functional/fix.cpp b/test/functional/fix.cpp index 1e52e4d29..3d02a703f 100644 --- a/test/functional/fix.cpp +++ b/test/functional/fix.cpp @@ -9,7 +9,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include #include -#include +#include using namespace boost::hana; diff --git a/test/include/test/auto/iterable.hpp b/test/include/test/auto/iterable.hpp index ab38d60d2..1e031c7cf 100644 --- a/test/include/test/auto/iterable.hpp +++ b/test/include/test/auto/iterable.hpp @@ -13,7 +13,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include #include -#include +#include #include #include #include diff --git a/test/include/test/auto/list.hpp b/test/include/test/auto/list.hpp index 11bdedfda..0adbc048e 100644 --- a/test/include/test/auto/list.hpp +++ b/test/include/test/auto/list.hpp @@ -14,7 +14,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include #include -#include +#include #include // provided instances diff --git a/test/include/test/auto/ring.hpp b/test/include/test/auto/ring.hpp index 1172580bb..e43ed66b5 100644 --- a/test/include/test/auto/ring.hpp +++ b/test/include/test/auto/ring.hpp @@ -12,7 +12,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include #include -#include +#include #include #include diff --git a/test/integer_list.cpp b/test/integer_list.cpp index b29db589a..868ee8e3e 100644 --- a/test/integer_list.cpp +++ b/test/integer_list.cpp @@ -7,7 +7,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include -#include +#include #include #include @@ -84,19 +84,19 @@ int main() { // cons { BOOST_HANA_CONSTANT_CHECK(equal( - cons(integral, integer_list), + cons(int_<0>, integer_list), integer_list )); BOOST_HANA_CONSTANT_CHECK(equal( - cons(integral, integer_list), + cons(int_<0>, integer_list), integer_list )); BOOST_HANA_CONSTANT_CHECK(equal( - cons(integral, integer_list), + cons(long_<0>, integer_list), integer_list )); BOOST_HANA_CONSTANT_CHECK(equal( - cons(integral, integer_list), + cons(ulong<0>, integer_list), integer_list )); } diff --git a/test/integral.cpp b/test/integral_constant.cpp similarity index 88% rename from test/integral.cpp rename to test/integral_constant.cpp index a63708306..4f7501433 100644 --- a/test/integral.cpp +++ b/test/integral_constant.cpp @@ -4,7 +4,7 @@ Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) */ -#include +#include #include #include @@ -19,24 +19,24 @@ using namespace boost::hana; namespace boost { namespace hana { namespace test { template - auto objects> = tuple( - integral, - integral, - integral, - integral + auto objects> = tuple( + integral_constant, + integral_constant, + integral_constant, + integral_constant ); template - auto instances> = tuple( + auto instances> = tuple( type ); }}} int main() { - test::check_datatype>(); + test::check_datatype>(); - // Integral's API (like std::integral_constant) + // IntegralConstant's API (like std::integral_constant) { // operator() static_assert(size_t<0>() == 0, ""); @@ -133,8 +133,8 @@ int main() { { // value { - static_assert(value(integral) == 0, ""); - static_assert(value(integral) == 1, ""); + static_assert(value(integral_constant) == 0, ""); + static_assert(value(integral_constant) == 1, ""); } } } diff --git a/test/range.cpp b/test/range.cpp index 54ee8182e..0b32206d2 100644 --- a/test/range.cpp +++ b/test/range.cpp @@ -7,7 +7,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include -#include +#include #include #include @@ -53,28 +53,28 @@ int main() { using T = int; BOOST_HANA_CONSTANT_CHECK(equal( range_c, - range(integral, integral) + range(integral_constant, integral_constant) )); BOOST_HANA_CONSTANT_CHECK(equal( range_c, - range(integral, integral) + range(integral_constant, integral_constant) )); BOOST_HANA_CONSTANT_CHECK(equal( range_c, - range(integral, integral) + range(integral_constant, integral_constant) )); BOOST_HANA_CONSTANT_CHECK(equal( range_c, - range(integral, integral) + range(integral_constant, integral_constant) )); BOOST_HANA_CONSTANT_CHECK(equal( range_c, - range(integral, integral) + range(integral_constant, integral_constant) )); BOOST_HANA_CONSTANT_CHECK(equal( range_c, - range(integral, integral) + range(integral_constant, integral_constant) )); } diff --git a/test/record_macros.cpp b/test/record_macros.cpp index 7cef0309c..ab8939807 100644 --- a/test/record_macros.cpp +++ b/test/record_macros.cpp @@ -10,7 +10,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include -#include +#include #include #include #include diff --git a/test/sandbox/function.cpp b/test/sandbox/function.cpp index 7147adbd8..f2242e7fb 100644 --- a/test/sandbox/function.cpp +++ b/test/sandbox/function.cpp @@ -88,7 +88,7 @@ namespace boost { namespace hana { #include -#include +#include #include #include using namespace boost::hana; diff --git a/test/sandbox/hash_map.cpp b/test/sandbox/hash_map.cpp index 9e8269eba..a64cac0e2 100644 --- a/test/sandbox/hash_map.cpp +++ b/test/sandbox/hash_map.cpp @@ -9,7 +9,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include #include -#include +#include #include #include diff --git a/test/sandbox/repeat.cpp b/test/sandbox/repeat.cpp index d2c6924d7..96584239a 100644 --- a/test/sandbox/repeat.cpp +++ b/test/sandbox/repeat.cpp @@ -7,7 +7,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include #include -#include +#include #include #include #include diff --git a/test/sandbox/tuple_opts.cpp b/test/sandbox/tuple_opts.cpp index b0f899dd3..c40714cfa 100644 --- a/test/sandbox/tuple_opts.cpp +++ b/test/sandbox/tuple_opts.cpp @@ -43,7 +43,7 @@ auto tuple = [](auto ...xs) { }; template -constexpr auto constant = boost::hana::integral; +constexpr auto constant = boost::hana::integral_constant; @@ -134,11 +134,11 @@ namespace boost { namespace hana { template - static constexpr auto cons_helper(X x, decltype(::tuple()) const&, Integral) + static constexpr auto cons_helper(X x, decltype(::tuple()) const&, IntegralConstant) { return tuple_c; } template - static constexpr auto cons_helper(X x, ::detail::tuple_c xs, Integral) + static constexpr auto cons_helper(X x, ::detail::tuple_c xs, IntegralConstant) { return tuple_c; } diff --git a/test/seq/main.hpp b/test/seq/main.hpp index c7f6d6570..f6fbb02d9 100644 --- a/test/seq/main.hpp +++ b/test/seq/main.hpp @@ -8,7 +8,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include -#include +#include #include #include diff --git a/test/tuple.cpp b/test/tuple.cpp index def12d5c3..ca09001b0 100644 --- a/test/tuple.cpp +++ b/test/tuple.cpp @@ -6,7 +6,7 @@ Distributed under the Boost Software License, Version 1.0. #include -#include +#include #include #include diff --git a/test/type.cpp b/test/type.cpp index 45d334b2a..be1d832fa 100644 --- a/test/type.cpp +++ b/test/type.cpp @@ -7,7 +7,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include -#include +#include #include #include