diff options
author | DongHun Kwak <dh0128.kwak@samsung.com> | 2017-09-13 11:05:34 +0900 |
---|---|---|
committer | DongHun Kwak <dh0128.kwak@samsung.com> | 2017-09-13 11:06:28 +0900 |
commit | 34bd32e225e2a8a94104489b31c42e5801cc1f4a (patch) | |
tree | d021b579a0c190354819974e1eaf0baa54b551f3 /boost/hana | |
parent | f763a99a501650eff2c60288aa6f10ef916d769e (diff) | |
download | boost-34bd32e225e2a8a94104489b31c42e5801cc1f4a.tar.gz boost-34bd32e225e2a8a94104489b31c42e5801cc1f4a.tar.bz2 boost-34bd32e225e2a8a94104489b31c42e5801cc1f4a.zip |
Imported Upstream version 1.63.0upstream/1.63.0
Change-Id: Iac85556a04b7e58d63ba636dedb0986e3555714a
Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
Diffstat (limited to 'boost/hana')
46 files changed, 737 insertions, 462 deletions
diff --git a/boost/hana/at.hpp b/boost/hana/at.hpp index dc208323b1..86cab698c4 100644 --- a/boost/hana/at.hpp +++ b/boost/hana/at.hpp @@ -50,7 +50,7 @@ BOOST_HANA_NAMESPACE_BEGIN template <std::size_t n, typename Xs> constexpr decltype(auto) at_c(Xs&& xs) { - return hana::at(static_cast<Xs&&>(xs), hana::size_c<n>); + return hana::at(static_cast<Xs&&>(xs), hana::size_t<n>{}); } BOOST_HANA_NAMESPACE_END diff --git a/boost/hana/basic_tuple.hpp b/boost/hana/basic_tuple.hpp index 50af4e33f5..8651e464bf 100644 --- a/boost/hana/basic_tuple.hpp +++ b/boost/hana/basic_tuple.hpp @@ -259,8 +259,9 @@ BOOST_HANA_NAMESPACE_BEGIN template <> struct is_empty_impl<basic_tuple_tag> { template <typename ...Xs> - static constexpr auto apply(basic_tuple<Xs...> const&) - { return hana::bool_c<sizeof...(Xs) == 0>; } + static constexpr hana::bool_<sizeof...(Xs) == 0> + apply(basic_tuple<Xs...> const&) + { return {}; } }; ////////////////////////////////////////////////////////////////////////// diff --git a/boost/hana/bool.hpp b/boost/hana/bool.hpp index e69654dd85..7ba1bfcb6c 100644 --- a/boost/hana/bool.hpp +++ b/boost/hana/bool.hpp @@ -192,8 +192,9 @@ BOOST_HANA_NAMESPACE_BEGIN namespace literals { template <char ...c> - constexpr auto operator"" _c() - { return llong_c<ic_detail::parse<sizeof...(c)>({c...})>; } + constexpr auto operator"" _c() { + return hana::llong<ic_detail::parse<sizeof...(c)>({c...})>{}; + } } ////////////////////////////////////////////////////////////////////////// @@ -221,8 +222,10 @@ BOOST_HANA_NAMESPACE_BEGIN template <typename Cond, typename Then, typename Else> static constexpr decltype(auto) apply(Cond const&, Then&& t, Else&& e) { - return eval_if_impl::apply(hana::bool_c<static_cast<bool>(Cond::value)>, - static_cast<Then&&>(t), static_cast<Else&&>(e)); + constexpr bool cond = static_cast<bool>(Cond::value); + return eval_if_impl::apply(hana::bool_<cond>{}, + static_cast<Then&&>(t), + static_cast<Else&&>(e)); } template <typename Then, typename Else> @@ -241,8 +244,10 @@ BOOST_HANA_NAMESPACE_BEGIN template <typename Cond, typename Then, typename Else> static constexpr decltype(auto) apply(Cond const&, Then&& t, Else&& e) { - return if_impl::apply(hana::bool_c<static_cast<bool>(Cond::value)>, - static_cast<Then&&>(t), static_cast<Else&&>(e)); + constexpr bool cond = static_cast<bool>(Cond::value); + return if_impl::apply(hana::bool_<cond>{}, + static_cast<Then&&>(t), + static_cast<Else&&>(e)); } //! @todo We could return `Then` instead of `auto` to sometimes save diff --git a/boost/hana/concept.hpp b/boost/hana/concept.hpp index c8decf9925..0ae73d8b7b 100644 --- a/boost/hana/concept.hpp +++ b/boost/hana/concept.hpp @@ -18,6 +18,7 @@ Distributed under the Boost Software License, Version 1.0. #include <boost/hana/concept/foldable.hpp> #include <boost/hana/concept/functor.hpp> #include <boost/hana/concept/group.hpp> +#include <boost/hana/concept/hashable.hpp> #include <boost/hana/concept/integral_constant.hpp> #include <boost/hana/concept/iterable.hpp> #include <boost/hana/concept/logical.hpp> diff --git a/boost/hana/concept/applicative.hpp b/boost/hana/concept/applicative.hpp index 28c3af4242..9227b1d1d1 100644 --- a/boost/hana/concept/applicative.hpp +++ b/boost/hana/concept/applicative.hpp @@ -16,16 +16,18 @@ Distributed under the Boost Software License, Version 1.0. #include <boost/hana/config.hpp> #include <boost/hana/core/default.hpp> #include <boost/hana/core/tag_of.hpp> +#include <boost/hana/detail/integral_constant.hpp> #include <boost/hana/lift.hpp> BOOST_HANA_NAMESPACE_BEGIN template <typename A> - struct Applicative { - using Tag = typename tag_of<A>::type; - static constexpr bool value = !is_default<ap_impl<Tag>>::value && - !is_default<lift_impl<Tag>>::value; - }; + struct Applicative + : hana::integral_constant<bool, + !is_default<ap_impl<typename tag_of<A>::type>>::value && + !is_default<lift_impl<typename tag_of<A>::type>>::value + > + { }; BOOST_HANA_NAMESPACE_END #endif // !BOOST_HANA_CONCEPT_APPLICATIVE_HPP diff --git a/boost/hana/concept/comonad.hpp b/boost/hana/concept/comonad.hpp index 4aff1ab648..5d3a49a4e8 100644 --- a/boost/hana/concept/comonad.hpp +++ b/boost/hana/concept/comonad.hpp @@ -15,6 +15,7 @@ Distributed under the Boost Software License, Version 1.0. #include <boost/hana/config.hpp> #include <boost/hana/core/default.hpp> #include <boost/hana/core/tag_of.hpp> +#include <boost/hana/detail/integral_constant.hpp> #include <boost/hana/duplicate.hpp> #include <boost/hana/extend.hpp> #include <boost/hana/extract.hpp> @@ -22,12 +23,13 @@ Distributed under the Boost Software License, Version 1.0. BOOST_HANA_NAMESPACE_BEGIN template <typename W> - struct Comonad { - using Tag = typename tag_of<W>::type; - static constexpr bool value = !is_default<extract_impl<Tag>>::value && - (!is_default<duplicate_impl<Tag>>::value || - !is_default<extend_impl<Tag>>::value); - }; + struct Comonad + : hana::integral_constant<bool, + !is_default<extract_impl<typename tag_of<W>::type>>::value && + (!is_default<duplicate_impl<typename tag_of<W>::type>>::value || + !is_default<extend_impl<typename tag_of<W>::type>>::value) + > + { }; BOOST_HANA_NAMESPACE_END #endif // !BOOST_HANA_CONCEPT_COMONAD_HPP diff --git a/boost/hana/concept/comparable.hpp b/boost/hana/concept/comparable.hpp index a38e5c6747..96c28be7e9 100644 --- a/boost/hana/concept/comparable.hpp +++ b/boost/hana/concept/comparable.hpp @@ -15,15 +15,18 @@ Distributed under the Boost Software License, Version 1.0. #include <boost/hana/config.hpp> #include <boost/hana/core/default.hpp> #include <boost/hana/core/tag_of.hpp> +#include <boost/hana/detail/integral_constant.hpp> #include <boost/hana/equal.hpp> BOOST_HANA_NAMESPACE_BEGIN template <typename T> - struct Comparable { - using Tag = typename tag_of<T>::type; - static constexpr bool value = !is_default<equal_impl<Tag, Tag>>::value; - }; + struct Comparable + : hana::integral_constant<bool, + !is_default<equal_impl<typename tag_of<T>::type, + typename tag_of<T>::type>>::value + > + { }; BOOST_HANA_NAMESPACE_END #endif // !BOOST_HANA_CONCEPT_COMPARABLE_HPP diff --git a/boost/hana/concept/constant.hpp b/boost/hana/concept/constant.hpp index 1c85a20739..08e5db248f 100644 --- a/boost/hana/concept/constant.hpp +++ b/boost/hana/concept/constant.hpp @@ -15,15 +15,17 @@ Distributed under the Boost Software License, Version 1.0. #include <boost/hana/config.hpp> #include <boost/hana/core/default.hpp> #include <boost/hana/core/tag_of.hpp> +#include <boost/hana/detail/integral_constant.hpp> #include <boost/hana/value.hpp> BOOST_HANA_NAMESPACE_BEGIN template <typename C> - struct Constant { - using Tag = typename tag_of<C>::type; - static constexpr bool value = !is_default<value_impl<Tag>>::value; - }; + struct Constant + : hana::integral_constant<bool, + !is_default<value_impl<typename tag_of<C>::type>>::value + > + { }; BOOST_HANA_NAMESPACE_END #endif // !BOOST_HANA_CONCEPT_CONSTANT_HPP diff --git a/boost/hana/concept/euclidean_ring.hpp b/boost/hana/concept/euclidean_ring.hpp index 19ee1abcd5..c58cb9fc45 100644 --- a/boost/hana/concept/euclidean_ring.hpp +++ b/boost/hana/concept/euclidean_ring.hpp @@ -15,17 +15,21 @@ Distributed under the Boost Software License, Version 1.0. #include <boost/hana/config.hpp> #include <boost/hana/core/default.hpp> #include <boost/hana/core/tag_of.hpp> +#include <boost/hana/detail/integral_constant.hpp> #include <boost/hana/div.hpp> #include <boost/hana/mod.hpp> BOOST_HANA_NAMESPACE_BEGIN template <typename R> - struct EuclideanRing { - using Tag = typename tag_of<R>::type; - static constexpr bool value = !is_default<mod_impl<Tag, Tag>>::value && - !is_default<div_impl<Tag, Tag>>::value; - }; + struct EuclideanRing + : hana::integral_constant<bool, + !is_default<mod_impl<typename tag_of<R>::type, + typename tag_of<R>::type>>::value && + !is_default<div_impl<typename tag_of<R>::type, + typename tag_of<R>::type>>::value + > + { }; BOOST_HANA_NAMESPACE_END #endif // !BOOST_HANA_CONCEPT_EUCLIDEAN_RING_HPP diff --git a/boost/hana/concept/foldable.hpp b/boost/hana/concept/foldable.hpp index 7737a74ce0..5efd153c2f 100644 --- a/boost/hana/concept/foldable.hpp +++ b/boost/hana/concept/foldable.hpp @@ -15,17 +15,19 @@ Distributed under the Boost Software License, Version 1.0. #include <boost/hana/config.hpp> #include <boost/hana/core/default.hpp> #include <boost/hana/core/tag_of.hpp> +#include <boost/hana/detail/integral_constant.hpp> #include <boost/hana/fold_left.hpp> #include <boost/hana/unpack.hpp> BOOST_HANA_NAMESPACE_BEGIN template <typename T> - struct Foldable { - using Tag = typename tag_of<T>::type; - static constexpr bool value = !is_default<fold_left_impl<Tag>>::value || - !is_default<unpack_impl<Tag>>::value; - }; + struct Foldable + : hana::integral_constant<bool, + !is_default<fold_left_impl<typename tag_of<T>::type>>::value || + !is_default<unpack_impl<typename tag_of<T>::type>>::value + > + { }; BOOST_HANA_NAMESPACE_END #endif // !BOOST_HANA_CONCEPT_FOLDABLE_HPP diff --git a/boost/hana/concept/functor.hpp b/boost/hana/concept/functor.hpp index 308abae56f..1a84126f6f 100644 --- a/boost/hana/concept/functor.hpp +++ b/boost/hana/concept/functor.hpp @@ -12,20 +12,22 @@ Distributed under the Boost Software License, Version 1.0. #include <boost/hana/fwd/concept/functor.hpp> -#include <boost/hana/config.hpp> #include <boost/hana/adjust_if.hpp> +#include <boost/hana/config.hpp> #include <boost/hana/core/default.hpp> #include <boost/hana/core/tag_of.hpp> +#include <boost/hana/detail/integral_constant.hpp> #include <boost/hana/transform.hpp> BOOST_HANA_NAMESPACE_BEGIN template <typename F> - struct Functor { - using Tag = typename tag_of<F>::type; - static constexpr bool value = !is_default<transform_impl<Tag>>::value || - !is_default<adjust_if_impl<Tag>>::value; - }; + struct Functor + : hana::integral_constant<bool, + !is_default<transform_impl<typename tag_of<F>::type>>::value || + !is_default<adjust_if_impl<typename tag_of<F>::type>>::value + > + { }; BOOST_HANA_NAMESPACE_END #endif // !BOOST_HANA_CONCEPT_FUNCTOR_HPP diff --git a/boost/hana/concept/group.hpp b/boost/hana/concept/group.hpp index 025537110a..5c8c34edf5 100644 --- a/boost/hana/concept/group.hpp +++ b/boost/hana/concept/group.hpp @@ -15,17 +15,20 @@ Distributed under the Boost Software License, Version 1.0. #include <boost/hana/config.hpp> #include <boost/hana/core/default.hpp> #include <boost/hana/core/tag_of.hpp> +#include <boost/hana/detail/integral_constant.hpp> #include <boost/hana/minus.hpp> #include <boost/hana/negate.hpp> BOOST_HANA_NAMESPACE_BEGIN template <typename G> - struct Group { - using Tag = typename tag_of<G>::type; - static constexpr bool value = !is_default<negate_impl<Tag>>::value || - !is_default<minus_impl<Tag, Tag>>::value; - }; + struct Group + : hana::integral_constant<bool, + !is_default<negate_impl<typename tag_of<G>::type>>::value || + !is_default<minus_impl<typename tag_of<G>::type, + typename tag_of<G>::type>>::value + > + { }; BOOST_HANA_NAMESPACE_END #endif // !BOOST_HANA_CONCEPT_GROUP_HPP diff --git a/boost/hana/concept/hashable.hpp b/boost/hana/concept/hashable.hpp index 9fc282fb71..b5a0ca0feb 100644 --- a/boost/hana/concept/hashable.hpp +++ b/boost/hana/concept/hashable.hpp @@ -16,15 +16,17 @@ Distributed under the Boost Software License, Version 1.0. #include <boost/hana/config.hpp> #include <boost/hana/core/default.hpp> #include <boost/hana/core/tag_of.hpp> +#include <boost/hana/detail/integral_constant.hpp> #include <boost/hana/hash.hpp> BOOST_HANA_NAMESPACE_BEGIN template <typename T> - struct Hashable { - using Tag = typename tag_of<T>::type; - static constexpr bool value = !is_default<hash_impl<Tag>>::value; - }; + struct Hashable + : hana::integral_constant<bool, + !is_default<hash_impl<typename tag_of<T>::type>>::value + > + { }; BOOST_HANA_NAMESPACE_END #endif // !BOOST_HANA_CONCEPT_HASHABLE_HPP diff --git a/boost/hana/concept/integral_constant.hpp b/boost/hana/concept/integral_constant.hpp index 6e36551001..599adf5bef 100644 --- a/boost/hana/concept/integral_constant.hpp +++ b/boost/hana/concept/integral_constant.hpp @@ -14,19 +14,22 @@ Distributed under the Boost Software License, Version 1.0. #include <boost/hana/config.hpp> #include <boost/hana/core/tag_of.hpp> +#include <boost/hana/detail/integral_constant.hpp> BOOST_HANA_NAMESPACE_BEGIN namespace detail { template <typename C, typename Tag = typename tag_of<C>::type> - struct integral_constant_dispatch { - static constexpr bool value = hana::IntegralConstant<Tag>::value; - }; + struct integral_constant_dispatch + : hana::integral_constant<bool, + hana::IntegralConstant<Tag>::value + > + { }; template <typename C> - struct integral_constant_dispatch<C, C> { - static constexpr bool value = false; - }; + struct integral_constant_dispatch<C, C> + : hana::integral_constant<bool, false> + { }; } //! @cond diff --git a/boost/hana/concept/iterable.hpp b/boost/hana/concept/iterable.hpp index 78c1914077..9cf68b7b43 100644 --- a/boost/hana/concept/iterable.hpp +++ b/boost/hana/concept/iterable.hpp @@ -12,22 +12,24 @@ Distributed under the Boost Software License, Version 1.0. #include <boost/hana/fwd/concept/iterable.hpp> -#include <boost/hana/config.hpp> #include <boost/hana/at.hpp> +#include <boost/hana/config.hpp> #include <boost/hana/core/default.hpp> #include <boost/hana/core/tag_of.hpp> +#include <boost/hana/detail/integral_constant.hpp> #include <boost/hana/drop_front.hpp> #include <boost/hana/is_empty.hpp> BOOST_HANA_NAMESPACE_BEGIN template <typename It> - struct Iterable { - using Tag = typename tag_of<It>::type; - static constexpr bool value = !is_default<at_impl<Tag>>::value && - !is_default<drop_front_impl<Tag>>::value && - !is_default<is_empty_impl<Tag>>::value; - }; + struct Iterable + : hana::integral_constant<bool, + !is_default<at_impl<typename tag_of<It>::type>>::value && + !is_default<drop_front_impl<typename tag_of<It>::type>>::value && + !is_default<is_empty_impl<typename tag_of<It>::type>>::value + > + { }; BOOST_HANA_NAMESPACE_END #endif // !BOOST_HANA_CONCEPT_ITERABLE_HPP diff --git a/boost/hana/concept/logical.hpp b/boost/hana/concept/logical.hpp index 74c0fb3a51..ecfd0a4ebe 100644 --- a/boost/hana/concept/logical.hpp +++ b/boost/hana/concept/logical.hpp @@ -15,6 +15,7 @@ Distributed under the Boost Software License, Version 1.0. #include <boost/hana/config.hpp> #include <boost/hana/core/default.hpp> #include <boost/hana/core/tag_of.hpp> +#include <boost/hana/detail/integral_constant.hpp> #include <boost/hana/eval_if.hpp> #include <boost/hana/not.hpp> #include <boost/hana/while.hpp> @@ -22,12 +23,13 @@ Distributed under the Boost Software License, Version 1.0. BOOST_HANA_NAMESPACE_BEGIN template <typename L> - struct Logical { - using Tag = typename tag_of<L>::type; - static constexpr bool value = !is_default<eval_if_impl<Tag>>::value && - !is_default<not_impl<Tag>>::value && - !is_default<while_impl<Tag>>::value; - }; + struct Logical + : hana::integral_constant<bool, + !is_default<eval_if_impl<typename tag_of<L>::type>>::value && + !is_default<not_impl<typename tag_of<L>::type>>::value && + !is_default<while_impl<typename tag_of<L>::type>>::value + > + { }; BOOST_HANA_NAMESPACE_END #endif // !BOOST_HANA_CONCEPT_LOGICAL_HPP diff --git a/boost/hana/concept/metafunction.hpp b/boost/hana/concept/metafunction.hpp index ed6d53ad87..61713e2b2e 100644 --- a/boost/hana/concept/metafunction.hpp +++ b/boost/hana/concept/metafunction.hpp @@ -14,19 +14,22 @@ Distributed under the Boost Software License, Version 1.0. #include <boost/hana/config.hpp> #include <boost/hana/core/tag_of.hpp> +#include <boost/hana/detail/integral_constant.hpp> BOOST_HANA_NAMESPACE_BEGIN namespace detail { template <typename F, typename Tag = typename tag_of<F>::type> - struct metafunction_dispatch { - static constexpr bool value = Metafunction<Tag>::value; - }; + struct metafunction_dispatch + : hana::integral_constant<bool, + Metafunction<Tag>::value + > + { }; template <typename F> - struct metafunction_dispatch<F, F> { - static constexpr bool value = false; - }; + struct metafunction_dispatch<F, F> + : hana::integral_constant<bool, false> + { }; } template <typename F> diff --git a/boost/hana/concept/monad.hpp b/boost/hana/concept/monad.hpp index ba1c33021f..e586192b4a 100644 --- a/boost/hana/concept/monad.hpp +++ b/boost/hana/concept/monad.hpp @@ -16,16 +16,18 @@ Distributed under the Boost Software License, Version 1.0. #include <boost/hana/config.hpp> #include <boost/hana/core/default.hpp> #include <boost/hana/core/tag_of.hpp> +#include <boost/hana/detail/integral_constant.hpp> #include <boost/hana/flatten.hpp> BOOST_HANA_NAMESPACE_BEGIN template <typename M> - struct Monad { - using Tag = typename tag_of<M>::type; - static constexpr bool value = !is_default<flatten_impl<Tag>>::value || - !is_default<chain_impl<Tag>>::value; - }; + struct Monad + : hana::integral_constant<bool, + !is_default<flatten_impl<typename tag_of<M>::type>>::value || + !is_default<chain_impl<typename tag_of<M>::type>>::value + > + { }; BOOST_HANA_NAMESPACE_END #endif // !BOOST_HANA_CONCEPT_MONAD_HPP diff --git a/boost/hana/concept/monad_plus.hpp b/boost/hana/concept/monad_plus.hpp index 22c67ca255..c561e5af82 100644 --- a/boost/hana/concept/monad_plus.hpp +++ b/boost/hana/concept/monad_plus.hpp @@ -16,16 +16,18 @@ Distributed under the Boost Software License, Version 1.0. #include <boost/hana/config.hpp> #include <boost/hana/core/default.hpp> #include <boost/hana/core/tag_of.hpp> +#include <boost/hana/detail/integral_constant.hpp> #include <boost/hana/empty.hpp> BOOST_HANA_NAMESPACE_BEGIN template <typename M> - struct MonadPlus { - using Tag = typename tag_of<M>::type; - static constexpr bool value = !is_default<concat_impl<Tag>>::value && - !is_default<empty_impl<Tag>>::value; - }; + struct MonadPlus + : hana::integral_constant<bool, + !is_default<concat_impl<typename tag_of<M>::type>>::value && + !is_default<empty_impl<typename tag_of<M>::type>>::value + > + { }; BOOST_HANA_NAMESPACE_END #endif // !BOOST_HANA_CONCEPT_MONAD_PLUS_HPP diff --git a/boost/hana/concept/monoid.hpp b/boost/hana/concept/monoid.hpp index df84bb23e6..024ce4fe28 100644 --- a/boost/hana/concept/monoid.hpp +++ b/boost/hana/concept/monoid.hpp @@ -15,17 +15,20 @@ Distributed under the Boost Software License, Version 1.0. #include <boost/hana/config.hpp> #include <boost/hana/core/default.hpp> #include <boost/hana/core/tag_of.hpp> +#include <boost/hana/detail/integral_constant.hpp> #include <boost/hana/plus.hpp> #include <boost/hana/zero.hpp> BOOST_HANA_NAMESPACE_BEGIN template <typename M> - struct Monoid { - using Tag = typename tag_of<M>::type; - static constexpr bool value = !is_default<zero_impl<Tag>>::value && - !is_default<plus_impl<Tag, Tag>>::value; - }; + struct Monoid + : hana::integral_constant<bool, + !is_default<zero_impl<typename tag_of<M>::type>>::value && + !is_default<plus_impl<typename tag_of<M>::type, + typename tag_of<M>::type>>::value + > + { }; BOOST_HANA_NAMESPACE_END #endif // !BOOST_HANA_CONCEPT_MONOID_HPP diff --git a/boost/hana/concept/orderable.hpp b/boost/hana/concept/orderable.hpp index 5461332cd4..1e9303d204 100644 --- a/boost/hana/concept/orderable.hpp +++ b/boost/hana/concept/orderable.hpp @@ -15,15 +15,18 @@ Distributed under the Boost Software License, Version 1.0. #include <boost/hana/config.hpp> #include <boost/hana/core/default.hpp> #include <boost/hana/core/tag_of.hpp> +#include <boost/hana/detail/integral_constant.hpp> #include <boost/hana/less.hpp> BOOST_HANA_NAMESPACE_BEGIN template <typename Ord> - struct Orderable { - using Tag = typename tag_of<Ord>::type; - static constexpr bool value = !is_default<less_impl<Tag, Tag>>::value; - }; + struct Orderable + : hana::integral_constant<bool, + !is_default<less_impl<typename tag_of<Ord>::type, + typename tag_of<Ord>::type>>::value + > + { }; BOOST_HANA_NAMESPACE_END #endif // !BOOST_HANA_CONCEPT_ORDERABLE_HPP diff --git a/boost/hana/concept/product.hpp b/boost/hana/concept/product.hpp index 1a77777b29..3ad8a70f2b 100644 --- a/boost/hana/concept/product.hpp +++ b/boost/hana/concept/product.hpp @@ -15,17 +15,19 @@ Distributed under the Boost Software License, Version 1.0. #include <boost/hana/config.hpp> #include <boost/hana/core/default.hpp> #include <boost/hana/core/tag_of.hpp> +#include <boost/hana/detail/integral_constant.hpp> #include <boost/hana/first.hpp> #include <boost/hana/second.hpp> BOOST_HANA_NAMESPACE_BEGIN template <typename P> - struct Product { - using Tag = typename tag_of<P>::type; - static constexpr bool value = !is_default<first_impl<Tag>>::value && - !is_default<second_impl<Tag>>::value; - }; + struct Product + : hana::integral_constant<bool, + !is_default<first_impl<typename tag_of<P>::type>>::value && + !is_default<second_impl<typename tag_of<P>::type>>::value + > + { }; BOOST_HANA_NAMESPACE_END #endif // !BOOST_HANA_CONCEPT_PRODUCT_HPP diff --git a/boost/hana/concept/ring.hpp b/boost/hana/concept/ring.hpp index 3cc309e68a..700b3f6bb8 100644 --- a/boost/hana/concept/ring.hpp +++ b/boost/hana/concept/ring.hpp @@ -15,17 +15,20 @@ Distributed under the Boost Software License, Version 1.0. #include <boost/hana/config.hpp> #include <boost/hana/core/default.hpp> #include <boost/hana/core/tag_of.hpp> +#include <boost/hana/detail/integral_constant.hpp> #include <boost/hana/mult.hpp> #include <boost/hana/one.hpp> BOOST_HANA_NAMESPACE_BEGIN template <typename R> - struct Ring { - using Tag = typename tag_of<R>::type; - static constexpr bool value = !is_default<one_impl<Tag>>::value && - !is_default<mult_impl<Tag, Tag>>::value; - }; + struct Ring + : hana::integral_constant<bool, + !is_default<one_impl<typename tag_of<R>::type>>::value && + !is_default<mult_impl<typename tag_of<R>::type, + typename tag_of<R>::type>>::value + > + { }; BOOST_HANA_NAMESPACE_END #endif // !BOOST_HANA_CONCEPT_RING_HPP diff --git a/boost/hana/concept/searchable.hpp b/boost/hana/concept/searchable.hpp index 923b57dfcf..0ee98907bf 100644 --- a/boost/hana/concept/searchable.hpp +++ b/boost/hana/concept/searchable.hpp @@ -16,16 +16,18 @@ Distributed under the Boost Software License, Version 1.0. #include <boost/hana/config.hpp> #include <boost/hana/core/default.hpp> #include <boost/hana/core/tag_of.hpp> +#include <boost/hana/detail/integral_constant.hpp> #include <boost/hana/find_if.hpp> BOOST_HANA_NAMESPACE_BEGIN template <typename S> - struct Searchable { - using Tag = typename tag_of<S>::type; - static constexpr bool value = !is_default<any_of_impl<Tag>>::value && - !is_default<find_if_impl<Tag>>::value; - }; + struct Searchable + : hana::integral_constant<bool, + !is_default<any_of_impl<typename tag_of<S>::type>>::value && + !is_default<find_if_impl<typename tag_of<S>::type>>::value + > + { }; BOOST_HANA_NAMESPACE_END #endif // !BOOST_HANA_CONCEPT_SEARCHABLE_HPP diff --git a/boost/hana/concept/sequence.hpp b/boost/hana/concept/sequence.hpp index b2c6cda50c..fb5b83a2de 100644 --- a/boost/hana/concept/sequence.hpp +++ b/boost/hana/concept/sequence.hpp @@ -15,19 +15,22 @@ Distributed under the Boost Software License, Version 1.0. #include <boost/hana/config.hpp> #include <boost/hana/core/tag_of.hpp> #include <boost/hana/core/when.hpp> +#include <boost/hana/detail/integral_constant.hpp> BOOST_HANA_NAMESPACE_BEGIN namespace detail { template <typename S, typename Tag = typename hana::tag_of<S>::type> - struct sequence_dispatch { - static constexpr bool value = hana::Sequence<Tag>::value; - }; + struct sequence_dispatch + : hana::integral_constant<bool, + hana::Sequence<Tag>::value + > + { }; template <typename S> - struct sequence_dispatch<S, S> { - static constexpr bool value = false; - }; + struct sequence_dispatch<S, S> + : hana::integral_constant<bool, false> + { }; } //! @cond diff --git a/boost/hana/concept/struct.hpp b/boost/hana/concept/struct.hpp index 709d0cccea..62183f44f6 100644 --- a/boost/hana/concept/struct.hpp +++ b/boost/hana/concept/struct.hpp @@ -16,14 +16,16 @@ Distributed under the Boost Software License, Version 1.0. #include <boost/hana/config.hpp> #include <boost/hana/core/default.hpp> #include <boost/hana/core/tag_of.hpp> +#include <boost/hana/detail/integral_constant.hpp> BOOST_HANA_NAMESPACE_BEGIN template <typename S> - struct Struct { - using Tag = typename tag_of<S>::type; - static constexpr bool value = !is_default<accessors_impl<Tag>>::value; - }; + struct Struct + : hana::integral_constant<bool, + !is_default<accessors_impl<typename tag_of<S>::type>>::value + > + { }; BOOST_HANA_NAMESPACE_END #endif // !BOOST_HANA_CONCEPT_STRUCT_HPP diff --git a/boost/hana/config.hpp b/boost/hana/config.hpp index fd1939c09e..de7d1dc794 100644 --- a/boost/hana/config.hpp +++ b/boost/hana/config.hpp @@ -71,7 +71,11 @@ Distributed under the Boost Software License, Version 1.0. // Check the compiler for general C++14 capabilities ////////////////////////////////////////////////////////////////////////////// #if (__cplusplus < 201400) -# warning "Your compiler doesn't provide C++14 or higher capabilities. Try adding the compiler flag '-std=c++14' or '-std=c++1y'." +# if defined(_MSC_VER) +# pragma message("Warning: Your compiler doesn't provide C++14 or higher capabilities. Try adding the compiler flag '-std=c++14' or '-std=c++1y'.") +# else +# warning "Your compiler doesn't provide C++14 or higher capabilities. Try adding the compiler flag '-std=c++14' or '-std=c++1y'." +# endif #endif ////////////////////////////////////////////////////////////////////////////// diff --git a/boost/hana/detail/concepts.hpp b/boost/hana/detail/concepts.hpp index 4031f356df..6feed772c0 100644 --- a/boost/hana/detail/concepts.hpp +++ b/boost/hana/detail/concepts.hpp @@ -33,7 +33,7 @@ BOOST_HANA_NAMESPACE_BEGIN namespace detail { template <typename T, typename U> struct EqualityComparable<T, U, typename std::enable_if< - !std::is_same<T, U>{}, detail::void_t< + !std::is_same<T, U>::value, detail::void_t< decltype(static_cast<T&&>(*(T*)0) == static_cast<U&&>(*(U*)0) ? 0:0), decltype(static_cast<U&&>(*(U*)0) == static_cast<T&&>(*(T*)0) ? 0:0), decltype(static_cast<T&&>(*(T*)0) != static_cast<U&&>(*(U*)0) ? 0:0), diff --git a/boost/hana/detail/integral_constant.hpp b/boost/hana/detail/integral_constant.hpp new file mode 100644 index 0000000000..aded3ba331 --- /dev/null +++ b/boost/hana/detail/integral_constant.hpp @@ -0,0 +1,245 @@ +/*! +@file +Defines the barebones `boost::hana::integral_constant` template, but no +operations on it. + +@copyright Louis Dionne 2013-2016 +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_DETAIL_INTEGRAL_CONSTANT_HPP +#define BOOST_HANA_DETAIL_INTEGRAL_CONSTANT_HPP + +#include <boost/hana/config.hpp> +#include <boost/hana/detail/operators/adl.hpp> + +#include <type_traits> + + +BOOST_HANA_NAMESPACE_BEGIN + //! Tag representing `hana::integral_constant`. + //! @relates hana::integral_constant + template <typename T> + struct integral_constant_tag { + using value_type = T; + }; + + namespace ic_detail { + template <typename T, T v> + struct with_index_t { + template <typename F> + constexpr void operator()(F&& f) const; + }; + + template <typename T, T v> + struct times_t { + static constexpr with_index_t<T, v> with_index{}; + + template <typename F> + constexpr void operator()(F&& f) const; + }; + } + + //! @ingroup group-datatypes + //! Compile-time value of an integral type. + //! + //! An `integral_constant` is an object that represents a compile-time + //! integral value. As the name suggests, `hana::integral_constant` is + //! basically equivalent to `std::integral_constant`, except that + //! `hana::integral_constant` also provide other goodies to make them + //! easier to use, like arithmetic operators and similar features. In + //! particular, `hana::integral_constant` is guaranteed to inherit from + //! the corresponding `std::integral_constant`, and hence have the same + //! members and capabilities. The sections below explain the extensions + //! to `std::integral_constant` provided by `hana::integral_constant`. + //! + //! + //! Arithmetic operators + //! -------------------- + //! `hana::integral_constant` provides arithmetic operators that return + //! `hana::integral_constant`s to ease writing compile-time arithmetic: + //! @snippet example/integral_constant.cpp operators + //! + //! It is pretty important to realize that these operators return other + //! `integral_constant`s, not normal values of an integral type. + //! Actually, all those operators work pretty much in the same way. + //! Simply put, for an operator `@`, + //! @code + //! integral_constant<T, x>{} @ integral_constant<T, y>{} == integral_constant<T, x @ y>{} + //! @endcode + //! + //! The fact that the operators return `Constant`s is very important + //! because it allows all the information that's known at compile-time + //! to be conserved as long as it's only used with other values known at + //! compile-time. It is also interesting to observe that whenever an + //! `integral_constant` is combined with a normal runtime value, the + //! result will be a runtime value (because of the implicit conversion). + //! In general, this gives us the following table + //! + //! left operand | right operand | result + //! :-----------------: | :-----------------: | :-----------------: + //! `integral_constant` | `integral_constant` | `integral_constant` + //! `integral_constant` | runtime | runtime + //! runtime | `integral_constant` | runtime + //! runtime | runtime | runtime + //! + //! The full range of provided operators is + //! - Arithmetic: binary `+`, binary `-`, `/`, `*`, `%`, unary `+`, unary `-` + //! - Bitwise: `~`, `&`, `|`, `^`, `<<`, `>>` + //! - Comparison: `==`, `!=`, `<`, `<=`, `>`, `>=` + //! - %Logical: `||`, `&&`, `!` + //! + //! + //! Construction with user-defined literals + //! --------------------------------------- + //! `integral_constant`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` and `IntegralConstant`\n + //! An `integral_constant` is a model of the `IntegralConstant` concept in + //! the most obvious way possible. Specifically, + //! @code + //! integral_constant<T, v>::value == v // of type T + //! @endcode + //! The model of `Constant` follows naturally from the model of `IntegralConstant`, i.e. + //! @code + //! value<integral_constant<T, v>>() == v // of type T + //! @endcode + //! + //! 2. `Comparable`, `Orderable`, `Logical`, `Monoid`, `Group`, `Ring`, and `EuclideanRing`, `Hashable`\n + //! Those models are exactly those provided for `Constant`s, which are + //! documented in their respective concepts. +#ifdef BOOST_HANA_DOXYGEN_INVOKED + template <typename T, T v> + struct integral_constant { + //! Call a function n times. + //! + //! `times` 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, not just a + //! static function. This allows `int_<n>::%times` to be passed to + //! higher-order algorithms: + //! @snippet example/integral_constant.cpp times_higher_order + //! + //! Also, since static members can be accessed using both the `.` and + //! the `::` syntax, one can take advantage of this (loophole?) to + //! call `times` on objects just as well as on types: + //! @snippet example/integral_constant.cpp from_object + //! + //! @note + //! `times` is equivalent to the `hana::repeat` function, which works + //! on an arbitrary `IntegralConstant`. + //! + //! Sometimes, it is also useful to know the index we're at inside the + //! function. This can be achieved by using `times.with_index`: + //! @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 just a function object nested + //! inside `times`, which allows for this nice little interface. Also + //! note that the indices passed to the function are `integral_constant`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 + //! + //! @note + //! `times.with_index(f)` guarantees that the calls to `f` will be + //! done in order of ascending index. In other words, `f` will be + //! called as `f(0)`, `f(1)`, `f(2)`, etc., but with `integral_constant`s + //! instead of normal integers. Side effects can also be done in the + //! function passed to `times` and `times.with_index`. + template <typename F> + static constexpr void times(F&& f) { + f(); f(); ... f(); // n times total + } + + //! Equivalent to `hana::plus` + template <typename X, typename Y> + friend constexpr auto operator+(X&& x, Y&& y); + + //! Equivalent to `hana::minus` + template <typename X, typename Y> + friend constexpr auto operator-(X&& x, Y&& y); + + //! Equivalent to `hana::negate` + template <typename X> + friend constexpr auto operator-(X&& x); + + //! Equivalent to `hana::mult` + template <typename X, typename Y> + friend constexpr auto operator*(X&& x, Y&& y); + + //! Equivalent to `hana::div` + template <typename X, typename Y> + friend constexpr auto operator/(X&& x, Y&& y); + + //! Equivalent to `hana::mod` + template <typename X, typename Y> + friend constexpr auto operator%(X&& x, Y&& y); + + //! Equivalent to `hana::equal` + template <typename X, typename Y> + friend constexpr auto operator==(X&& x, Y&& y); + + //! Equivalent to `hana::not_equal` + template <typename X, typename Y> + friend constexpr auto operator!=(X&& x, Y&& y); + + //! Equivalent to `hana::or_` + template <typename X, typename Y> + friend constexpr auto operator||(X&& x, Y&& y); + + //! Equivalent to `hana::and_` + template <typename X, typename Y> + friend constexpr auto operator&&(X&& x, Y&& y); + + //! Equivalent to `hana::not_` + template <typename X> + friend constexpr auto operator!(X&& x); + + //! Equivalent to `hana::less` + template <typename X, typename Y> + friend constexpr auto operator<(X&& x, Y&& y); + + //! Equivalent to `hana::greater` + template <typename X, typename Y> + friend constexpr auto operator>(X&& x, Y&& y); + + //! Equivalent to `hana::less_equal` + template <typename X, typename Y> + friend constexpr auto operator<=(X&& x, Y&& y); + + //! Equivalent to `hana::greater_equal` + template <typename X, typename Y> + friend constexpr auto operator>=(X&& x, Y&& y); + }; +#else + template <typename T, T v> + struct integral_constant + : std::integral_constant<T, v> + , detail::operators::adl<integral_constant<T, v>> + { + using type = integral_constant; // override std::integral_constant::type + static constexpr ic_detail::times_t<T, v> times{}; + using hana_tag = integral_constant_tag<T>; + }; +#endif +BOOST_HANA_NAMESPACE_END + +#endif // !BOOST_HANA_DETAIL_INTEGRAL_CONSTANT_HPP diff --git a/boost/hana/detail/type_at.hpp b/boost/hana/detail/type_at.hpp new file mode 100644 index 0000000000..5875483d24 --- /dev/null +++ b/boost/hana/detail/type_at.hpp @@ -0,0 +1,57 @@ +/*! +@file +Defines `boost::hana::detail::type_at`. + +@copyright Louis Dionne 2013-2016 +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_DETAIL_TYPE_AT_HPP +#define BOOST_HANA_DETAIL_TYPE_AT_HPP + +#include <boost/hana/config.hpp> + +#include <cstddef> +#include <utility> + + +// If possible, use an intrinsic provided by Clang +#if defined(__has_builtin) +# if __has_builtin(__type_pack_element) +# define BOOST_HANA_USE_TYPE_PACK_ELEMENT_INTRINSIC +# endif +#endif + +BOOST_HANA_NAMESPACE_BEGIN namespace detail { + namespace td { + template <std::size_t I, typename T> + struct elt { using type = T; }; + + template <typename Indices, typename ...T> + struct indexer; + + template <std::size_t ...I, typename ...T> + struct indexer<std::index_sequence<I...>, T...> + : elt<I, T>... + { }; + + template <std::size_t I, typename T> + elt<I, T> get_elt(elt<I, T> const&); + } + + //! @ingroup group-details + //! Classic MPL-style metafunction returning the nth element of a type + //! parameter pack. + template <std::size_t n, typename ...T> + struct type_at { +#if defined(BOOST_HANA_USE_TYPE_PACK_ELEMENT_INTRINSIC) + using type = __type_pack_element<n, T...>; +#else + using Indexer = td::indexer<std::make_index_sequence<sizeof...(T)>, T...>; + using type = typename decltype(td::get_elt<n>(Indexer{}))::type; +#endif + }; +} BOOST_HANA_NAMESPACE_END + +#endif // !BOOST_HANA_DETAIL_TYPE_AT_HPP diff --git a/boost/hana/drop_front.hpp b/boost/hana/drop_front.hpp index 053a2f2b13..c06fbec593 100644 --- a/boost/hana/drop_front.hpp +++ b/boost/hana/drop_front.hpp @@ -43,7 +43,7 @@ BOOST_HANA_NAMESPACE_BEGIN template <typename Xs> constexpr auto drop_front_t::operator()(Xs&& xs) const { - return (*this)(static_cast<Xs&&>(xs), hana::size_c<1>); + return (*this)(static_cast<Xs&&>(xs), hana::size_t<1>{}); } //! @endcond diff --git a/boost/hana/equal.hpp b/boost/hana/equal.hpp index 498f7a8a2b..8eb0912fca 100644 --- a/boost/hana/equal.hpp +++ b/boost/hana/equal.hpp @@ -63,7 +63,11 @@ BOOST_HANA_NAMESPACE_BEGIN "types that can't be safely embedded into a common type, because " "those are most likely programming errors. If this is really what " "you want, you can manually convert both objects to a common " - "Comparable type before performing the comparison."); + "Comparable type before performing the comparison. If you think " + "you have made your types Comparable but you see this, perhaps you " + "forgot to define some of the necessary methods for an automatic " + "model of Comparable to kick in. A possible culprit is defining " + "'operator==' but not 'operator!='."); return hana::false_c; } @@ -105,7 +109,7 @@ BOOST_HANA_NAMESPACE_BEGIN static constexpr auto apply(X const&, Y const&) { constexpr auto eq = hana::equal(hana::value<X>(), hana::value<Y>()); constexpr bool truth_value = hana::if_(eq, true, false); - return hana::bool_c<truth_value>; + return hana::bool_<truth_value>{}; } }; @@ -135,7 +139,7 @@ BOOST_HANA_NAMESPACE_BEGIN template <std::size_t i> constexpr auto apply(hana::false_, hana::true_) const { return compare_finite_sequences::apply<i+1>( - hana::bool_c<i+1 == Length>, + hana::bool_<i+1 == Length>{}, hana::if_(hana::equal(hana::at_c<i>(xs), hana::at_c<i>(ys)), hana::true_c, hana::false_c) ); @@ -152,7 +156,7 @@ BOOST_HANA_NAMESPACE_BEGIN template <std::size_t i> constexpr bool apply(hana::false_, bool b) const { return b && compare_finite_sequences::apply<i+1>( - hana::bool_c<i+1 == Length>, + hana::bool_<i+1 == Length>{}, hana::if_(hana::equal(hana::at_c<i>(xs), hana::at_c<i>(ys)), hana::true_c, hana::false_c) ); @@ -167,8 +171,8 @@ BOOST_HANA_NAMESPACE_BEGIN constexpr std::size_t xs_size = decltype(hana::length(xs))::value; constexpr std::size_t ys_size = decltype(hana::length(ys))::value; detail::compare_finite_sequences<Xs, Ys, xs_size> comp{xs, ys}; - return comp.template apply<0>(hana::bool_c<xs_size == 0>, - hana::bool_c<xs_size == ys_size>); + return comp.template apply<0>(hana::bool_<xs_size == 0>{}, + hana::bool_<xs_size == ys_size>{}); } }; diff --git a/boost/hana/experimental/printable.hpp b/boost/hana/experimental/printable.hpp index 20993740dd..240e3a9291 100644 --- a/boost/hana/experimental/printable.hpp +++ b/boost/hana/experimental/printable.hpp @@ -41,6 +41,9 @@ Distributed under the Boost Software License, Version 1.0. BOOST_HANA_NAMESPACE_BEGIN namespace experimental { + template <typename T> + struct Printable; + //! @cond template <typename T, typename = void> struct print_impl : print_impl<T, hana::when<true>> { }; @@ -70,7 +73,16 @@ BOOST_HANA_NAMESPACE_BEGIN namespace experimental { struct print_t { template <typename T> std::string operator()(T const& t) const { - using Print = print_impl<typename hana::tag_of<T>::type>; + using Tag = typename hana::tag_of<T>::type; + using Print = BOOST_HANA_DISPATCH_IF(print_impl<Tag>, + hana::experimental::Printable<Tag>::value + ); + + #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS + static_assert(hana::experimental::Printable<Tag>::value, + "hana::experimental::print(t) requires 't' to be Printable"); + #endif + return Print::apply(t); } }; diff --git a/boost/hana/experimental/type_name.hpp b/boost/hana/experimental/type_name.hpp new file mode 100644 index 0000000000..764b7eedd9 --- /dev/null +++ b/boost/hana/experimental/type_name.hpp @@ -0,0 +1,64 @@ +/* +@file +Defines `boost::hana::experimental::type_name`. + +@copyright Louis Dionne 2013-2016 +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_EXPERIMENTAL_TYPE_NAME_HPP +#define BOOST_HANA_EXPERIMENTAL_TYPE_NAME_HPP + +#include <boost/hana/config.hpp> +#include <boost/hana/string.hpp> + +#include <cstddef> +#include <utility> + + +BOOST_HANA_NAMESPACE_BEGIN namespace experimental { + namespace detail { + struct cstring { + char const* ptr; + std::size_t length; + }; + + // Note: We substract the null terminator from the string sizes below. + template <typename T> + constexpr cstring type_name_impl2() { + + #if defined(__clang__) + constexpr char const* pretty_function = __PRETTY_FUNCTION__; + constexpr std::size_t total_size = sizeof(__PRETTY_FUNCTION__) - 1; + constexpr std::size_t prefix_size = sizeof("boost::hana::experimental::detail::cstring boost::hana::experimental::detail::type_name_impl2() [T = ") - 1; + constexpr std::size_t suffix_size = sizeof("]") - 1; + #else + #error "No support for this compiler." + #endif + + return {pretty_function + prefix_size, total_size - prefix_size - suffix_size}; + } + + template <typename T, std::size_t ...i> + auto type_name_impl1(std::index_sequence<i...>) { + constexpr auto name = detail::type_name_impl2<T>(); + return hana::string<*(name.ptr + i)...>{}; + } + } // end namespace detail + + //! @ingroup group-experimental + //! Returns a `hana::string` representing the name of the given type, at + //! compile-time. + //! + //! This only works on Clang (and apparently MSVC, but Hana does not work + //! there as of writing this). Original idea taken from + //! https://github.com/Manu343726/ctti. + template <typename T> + auto type_name() { + constexpr auto name = detail::type_name_impl2<T>(); + return detail::type_name_impl1<T>(std::make_index_sequence<name.length>{}); + } +} BOOST_HANA_NAMESPACE_END + +#endif // !BOOST_HANA_EXPERIMENTAL_TYPE_NAME_HPP diff --git a/boost/hana/experimental/types.hpp b/boost/hana/experimental/types.hpp index 86d9ddc957..75ae99e4f6 100644 --- a/boost/hana/experimental/types.hpp +++ b/boost/hana/experimental/types.hpp @@ -14,6 +14,7 @@ Distributed under the Boost Software License, Version 1.0. #include <boost/hana/concept/metafunction.hpp> #include <boost/hana/config.hpp> #include <boost/hana/detail/any_of.hpp> +#include <boost/hana/detail/type_at.hpp> #include <boost/hana/fwd/at.hpp> #include <boost/hana/fwd/contains.hpp> #include <boost/hana/fwd/core/tag_of.hpp> @@ -43,8 +44,6 @@ BOOST_HANA_NAMESPACE_BEGIN struct types_tag; - ////////////////////////////////////////////////////////////////////// - template <typename ...T> struct types { }; } // end namespace experimental @@ -88,30 +87,13 @@ BOOST_HANA_NAMESPACE_BEGIN apply(hana::experimental::types<T...> const&, F const&) { return {}; } }; - namespace types_detail { - template <std::size_t I, typename T> - struct elt { using type = T; }; - - template <typename Indices, typename ...T> - struct indexer; - - template <std::size_t ...I, typename ...T> - struct indexer<std::index_sequence<I...>, T...> - : elt<I, T>... - { }; - - template <std::size_t I, typename T> - elt<I, T> get_elt(elt<I, T> const&); - } - // Iterable template <> struct at_impl<hana::experimental::types_tag> { template <typename ...T, typename N> static constexpr auto apply(hana::experimental::types<T...> const&, N const&) { - using Indexer = types_detail::indexer<std::make_index_sequence<sizeof...(T)>, T...>; - using Nth = typename decltype(types_detail::get_elt<N::value>(Indexer{}))::type; + using Nth = typename detail::type_at<N::value, T...>::type; return hana::type<Nth>{}; } }; @@ -126,18 +108,16 @@ BOOST_HANA_NAMESPACE_BEGIN template <> struct drop_front_impl<hana::experimental::types_tag> { - template <std::size_t n, typename Indexer, std::size_t ...i> - static hana::experimental::types< - typename decltype(types_detail::get_elt<i + n>(Indexer{}))::type... - > helper(std::index_sequence<i...>); + template <std::size_t n, typename ...T, std::size_t ...i> + static hana::experimental::types<typename detail::type_at<i + n, T...>::type...> + helper(std::index_sequence<i...>); template <typename ...T, typename N> static constexpr auto apply(hana::experimental::types<T...> const&, N const&) { constexpr std::size_t n = N::value > sizeof...(T) ? sizeof...(T) : N::value; using Indices = std::make_index_sequence<sizeof...(T) - n>; - using Indexer = types_detail::indexer<std::make_index_sequence<sizeof...(T)>, T...>; - return decltype(helper<n, Indexer>(Indices{})){}; + return decltype(helper<n, T...>(Indices{})){}; } }; diff --git a/boost/hana/ext/std/array.hpp b/boost/hana/ext/std/array.hpp index f733624e57..15365f59cd 100644 --- a/boost/hana/ext/std/array.hpp +++ b/boost/hana/ext/std/array.hpp @@ -93,7 +93,7 @@ BOOST_HANA_NAMESPACE_BEGIN template <typename Xs, typename N> static constexpr decltype(auto) apply(Xs&& xs, N const&) { constexpr std::size_t n = N::value; - return static_cast<Xs&&>(xs)[n]; + return std::get<n>(static_cast<Xs&&>(xs)); } }; diff --git a/boost/hana/ext/std/integral_constant.hpp b/boost/hana/ext/std/integral_constant.hpp index 28d8f05fb8..48db42400c 100644 --- a/boost/hana/ext/std/integral_constant.hpp +++ b/boost/hana/ext/std/integral_constant.hpp @@ -85,7 +85,7 @@ BOOST_HANA_NAMESPACE_BEGIN template <typename T, typename C> struct to_impl<ext::std::integral_constant_tag<T>, C, when< hana::IntegralConstant<C>::value - >> : embedding<is_embedded<typename C::value_type, T>{}> { + >> : embedding<is_embedded<typename C::value_type, T>::value> { template <typename N> static constexpr auto apply(N const&) { return std::integral_constant<T, N::value>{}; diff --git a/boost/hana/fwd/concept/comparable.hpp b/boost/hana/fwd/concept/comparable.hpp index 1d4df7d635..555dfdfa34 100644 --- a/boost/hana/fwd/concept/comparable.hpp +++ b/boost/hana/fwd/concept/comparable.hpp @@ -49,14 +49,13 @@ BOOST_HANA_NAMESPACE_BEGIN //! Laws //! ---- //! `equal` must define an [equivalence relation][1], and `not_equal` must - //! be its complement. In other words, for all objects `a`, `b`, `c` of a - //! `Comparable` tag, the following must be true (where `x == y` and - //! `x != y` denote `equal(x, y)` and `not_equal(x, y)`, respectively): + //! be its complement. In other words, for all objects `a`, `b`, `c` with + //! a `Comparable` tag, the following must hold: //! @code - //! a == a // Reflexivity - //! if a == b then b == a // Symmetry - //! if a == b && b == c then a == c // Transitivity - //! a != b is equivalent to !(a == b) + //! equal(a, a) // Reflexivity + //! if equal(a, b) then equal(b, a) // Symmetry + //! if equal(a, b) && equal(b, c) then equal(a, c) // Transitivity + //! not_equal(a, b) is equivalent to not_(equal(a, b)) //! @endcode //! //! diff --git a/boost/hana/fwd/integral_constant.hpp b/boost/hana/fwd/integral_constant.hpp index e04eb8865d..d05d6021f9 100644 --- a/boost/hana/fwd/integral_constant.hpp +++ b/boost/hana/fwd/integral_constant.hpp @@ -11,236 +11,12 @@ Distributed under the Boost Software License, Version 1.0. #define BOOST_HANA_FWD_INTEGRAL_CONSTANT_HPP #include <boost/hana/config.hpp> -#include <boost/hana/detail/operators/adl.hpp> +#include <boost/hana/detail/integral_constant.hpp> #include <cstddef> -#include <type_traits> BOOST_HANA_NAMESPACE_BEGIN - //! Tag representing `hana::integral_constant`. - //! @relates hana::integral_constant - template <typename T> - struct integral_constant_tag { - using value_type = T; - }; - - namespace ic_detail { - template <typename T, T v> - struct with_index_t { - template <typename F> - constexpr void operator()(F&& f) const; - }; - - template <typename T, T v> - struct times_t { - static constexpr with_index_t<T, v> with_index{}; - - template <typename F> - constexpr void operator()(F&& f) const; - }; - } - - //! @ingroup group-datatypes - //! Compile-time value of an integral type. - //! - //! An `integral_constant` is an object that represents a compile-time - //! integral value. As the name suggests, `hana::integral_constant` is - //! basically equivalent to `std::integral_constant`, except that - //! `hana::integral_constant` also provide other goodies to make them - //! easier to use, like arithmetic operators and similar features. In - //! particular, `hana::integral_constant` is guaranteed to inherit from - //! the corresponding `std::integral_constant`, and hence have the same - //! members and capabilities. The sections below explain the extensions - //! to `std::integral_constant` provided by `hana::integral_constant`. - //! - //! - //! Arithmetic operators - //! -------------------- - //! `hana::integral_constant` provides arithmetic operators that return - //! `hana::integral_constant`s to ease writing compile-time arithmetic: - //! @snippet example/integral_constant.cpp operators - //! - //! It is pretty important to realize that these operators return other - //! `integral_constant`s, not normal values of an integral type. - //! Actually, all those operators work pretty much in the same way. - //! Simply put, for an operator `@`, - //! @code - //! integral_constant<T, x>{} @ integral_constant<T, y>{} == integral_constant<T, x @ y>{} - //! @endcode - //! - //! The fact that the operators return `Constant`s is very important - //! because it allows all the information that's known at compile-time - //! to be conserved as long as it's only used with other values known at - //! compile-time. It is also interesting to observe that whenever an - //! `integral_constant` is combined with a normal runtime value, the - //! result will be a runtime value (because of the implicit conversion). - //! In general, this gives us the following table - //! - //! left operand | right operand | result - //! :-----------------: | :-----------------: | :-----------------: - //! `integral_constant` | `integral_constant` | `integral_constant` - //! `integral_constant` | runtime | runtime - //! runtime | `integral_constant` | runtime - //! runtime | runtime | runtime - //! - //! The full range of provided operators is - //! - Arithmetic: binary `+`, binary `-`, `/`, `*`, `%`, unary `+`, unary `-` - //! - Bitwise: `~`, `&`, `|`, `^`, `<<`, `>>` - //! - Comparison: `==`, `!=`, `<`, `<=`, `>`, `>=` - //! - %Logical: `||`, `&&`, `!` - //! - //! - //! Construction with user-defined literals - //! --------------------------------------- - //! `integral_constant`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` and `IntegralConstant`\n - //! An `integral_constant` is a model of the `IntegralConstant` concept in - //! the most obvious way possible. Specifically, - //! @code - //! integral_constant<T, v>::value == v // of type T - //! @endcode - //! The model of `Constant` follows naturally from the model of `IntegralConstant`, i.e. - //! @code - //! value<integral_constant<T, v>>() == v // of type T - //! @endcode - //! - //! 2. `Comparable`, `Orderable`, `Logical`, `Monoid`, `Group`, `Ring`, and `EuclideanRing`, `Hashable`\n - //! Those models are exactly those provided for `Constant`s, which are - //! documented in their respective concepts. -#ifdef BOOST_HANA_DOXYGEN_INVOKED - template <typename T, T v> - struct integral_constant { - //! Call a function n times. - //! - //! `times` 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, not just a - //! static function. This allows `int_<n>::%times` to be passed to - //! higher-order algorithms: - //! @snippet example/integral_constant.cpp times_higher_order - //! - //! Also, since static members can be accessed using both the `.` and - //! the `::` syntax, one can take advantage of this (loophole?) to - //! call `times` on objects just as well as on types: - //! @snippet example/integral_constant.cpp from_object - //! - //! @note - //! `times` is equivalent to the `hana::repeat` function, which works - //! on an arbitrary `IntegralConstant`. - //! - //! Sometimes, it is also useful to know the index we're at inside the - //! function. This can be achieved by using `times.with_index`: - //! @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 just a function object nested - //! inside `times`, which allows for this nice little interface. Also - //! note that the indices passed to the function are `integral_constant`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 - //! - //! @note - //! `times.with_index(f)` guarantees that the calls to `f` will be - //! done in order of ascending index. In other words, `f` will be - //! called as `f(0)`, `f(1)`, `f(2)`, etc., but with `integral_constant`s - //! instead of normal integers. Side effects can also be done in the - //! function passed to `times` and `times.with_index`. - template <typename F> - static constexpr void times(F&& f) { - f(); f(); ... f(); // n times total - } - - //! Equivalent to `hana::plus` - template <typename X, typename Y> - friend constexpr auto operator+(X&& x, Y&& y); - - //! Equivalent to `hana::minus` - template <typename X, typename Y> - friend constexpr auto operator-(X&& x, Y&& y); - - //! Equivalent to `hana::negate` - template <typename X> - friend constexpr auto operator-(X&& x); - - //! Equivalent to `hana::mult` - template <typename X, typename Y> - friend constexpr auto operator*(X&& x, Y&& y); - - //! Equivalent to `hana::div` - template <typename X, typename Y> - friend constexpr auto operator/(X&& x, Y&& y); - - //! Equivalent to `hana::mod` - template <typename X, typename Y> - friend constexpr auto operator%(X&& x, Y&& y); - - //! Equivalent to `hana::equal` - template <typename X, typename Y> - friend constexpr auto operator==(X&& x, Y&& y); - - //! Equivalent to `hana::not_equal` - template <typename X, typename Y> - friend constexpr auto operator!=(X&& x, Y&& y); - - //! Equivalent to `hana::or_` - template <typename X, typename Y> - friend constexpr auto operator||(X&& x, Y&& y); - - //! Equivalent to `hana::and_` - template <typename X, typename Y> - friend constexpr auto operator&&(X&& x, Y&& y); - - //! Equivalent to `hana::not_` - template <typename X> - friend constexpr auto operator!(X&& x); - - //! Equivalent to `hana::less` - template <typename X, typename Y> - friend constexpr auto operator<(X&& x, Y&& y); - - //! Equivalent to `hana::greater` - template <typename X, typename Y> - friend constexpr auto operator>(X&& x, Y&& y); - - //! Equivalent to `hana::less_equal` - template <typename X, typename Y> - friend constexpr auto operator<=(X&& x, Y&& y); - - //! Equivalent to `hana::greater_equal` - template <typename X, typename Y> - friend constexpr auto operator>=(X&& x, Y&& y); - }; -#else - template <typename T, T v> - struct integral_constant - : std::integral_constant<T, v> - , detail::operators::adl<integral_constant<T, v>> - { - using type = integral_constant; // override std::integral_constant::type - static constexpr ic_detail::times_t<T, v> times{}; - using hana_tag = integral_constant_tag<T>; - }; -#endif - //! Creates an `integral_constant` holding the given compile-time value. //! @relates hana::integral_constant //! diff --git a/boost/hana/fwd/map.hpp b/boost/hana/fwd/map.hpp index 707cc0c6e9..25ff7add35 100644 --- a/boost/hana/fwd/map.hpp +++ b/boost/hana/fwd/map.hpp @@ -17,8 +17,14 @@ Distributed under the Boost Software License, Version 1.0. #include <boost/hana/fwd/insert.hpp> #include <boost/hana/fwd/keys.hpp> +#include <utility> + BOOST_HANA_NAMESPACE_BEGIN + //! Tag representing `hana::map`s. + //! @relates hana::map + struct map_tag { }; + //! @ingroup group-datatypes //! Basic associative container requiring unique, `Comparable` and //! `Hashable` keys. @@ -27,12 +33,21 @@ BOOST_HANA_NAMESPACE_BEGIN //! keys must be `Hashable`, and any two keys with equal hashes must be //! `Comparable` with each other at compile-time. //! - //! @note - //! The actual representation of a `hana::map` is implementation-defined. - //! In particular, one should not take for granted the order of the - //! template parameters and the presence of any additional constructors - //! or assignment operators than what is documented. The canonical way of - //! creating a `hana::map` is through `hana::make_map`. + //! Note that the actual representation of a `hana::map` is an implementation + //! detail. As such, one should not assume anything more than what is + //! explicitly documented as being part of the interface of a map, + //! such as: + //! - the presence of additional constructors + //! - the presence of additional assignment operators + //! - the fact that `hana::map<Pairs...>` is, or is not, a dependent type + //! + //! In particular, the last point is very important; `hana::map<Pairs...>` + //! is only a shortcut for + //! @code + //! decltype(hana::make_pair(std::declval<Pairs>()...)) + //! @endcode + //! which is not something that can be pattern-matched on during template + //! argument deduction, for example. //! //! //! Modeled concepts @@ -63,8 +78,13 @@ BOOST_HANA_NAMESPACE_BEGIN //! `Foldable` contains duplicate keys, only the value associated to the //! first occurence of each key is kept. //! @include example/map/to.cpp + //! + //! + //! Example + //! ------- + //! @include example/map/map.cpp #ifdef BOOST_HANA_DOXYGEN_INVOKED - template <typename implementation_defined> + template <typename ...Pairs> struct map { //! Default-construct a map. This constructor only exists when all the //! elements of the map are default-constructible. @@ -78,6 +98,14 @@ BOOST_HANA_NAMESPACE_BEGIN //! exists when all the elements of the map are move-constructible. constexpr map(map&& other) = default; + //! Construct the map from the provided pairs. `P...` must be pairs of + //! the same type (modulo ref and cv-qualifiers), and in the same order, + //! as those appearing in `Pairs...`. The pairs provided to this + //! constructor are emplaced into the map's storage using perfect + //! forwarding. + template <typename ...P> + explicit constexpr map(P&& ...pairs); + //! Equivalent to `hana::equal` template <typename X, typename Y> friend constexpr auto operator==(X&& x, Y&& y); @@ -91,14 +119,10 @@ BOOST_HANA_NAMESPACE_BEGIN constexpr decltype(auto) operator[](Key&& key); }; #else - template <typename HashTable, typename Storage> - struct map; + template <typename ...Pairs> + using map = decltype(hana::make<map_tag>(std::declval<Pairs>()...)); #endif - //! Tag representing `hana::map`s. - //! @relates hana::map - struct map_tag { }; - //! Function object for creating a `hana::map`. //! @relates hana::map //! diff --git a/boost/hana/fwd/string.hpp b/boost/hana/fwd/string.hpp index f96494b165..c3476d7e72 100644 --- a/boost/hana/fwd/string.hpp +++ b/boost/hana/fwd/string.hpp @@ -38,8 +38,8 @@ BOOST_HANA_NAMESPACE_BEGIN //! The representation of `hana::string` is implementation-defined. //! In particular, one should not take for granted that the template //! parameters are `char`s. The proper way to access the contents of - //! a `hana::string` as character constants is to use `hana::unpack` - //! or `hana::to<char const*>`, as documented below. + //! a `hana::string` as character constants is to use `hana::unpack`, + //! `.c_str()` or `hana::to<char const*>`, as documented below. //! //! //! Modeled concepts @@ -57,23 +57,28 @@ BOOST_HANA_NAMESPACE_BEGIN //! lexicographical comparison of strings. //! @include example/string/orderable.cpp //! - //! 3. `Foldable`\n + //! 3. `Monoid`\n + //! Strings form a monoid under concatenation, with the neutral element + //! being the empty string. + //! @include example/string/monoid.cpp + //! + //! 4. `Foldable`\n //! Folding a string is equivalent to folding the sequence of its //! characters. //! @include example/string/foldable.cpp //! - //! 4. `Iterable`\n + //! 5. `Iterable`\n //! Iterating over a string is equivalent to iterating over the sequence //! of its characters. Also note that `operator[]` can be used instead of //! the `at` function. //! @include example/string/iterable.cpp //! - //! 5. `Searchable`\n + //! 6. `Searchable`\n //! Searching through a string is equivalent to searching through the //! sequence of its characters. //! @include example/string/searchable.cpp //! - //! 6. `Hashable`\n + //! 7. `Hashable`\n //! The hash of a compile-time string is a type uniquely representing //! that string. //! @include example/string/hashable.cpp @@ -82,10 +87,11 @@ BOOST_HANA_NAMESPACE_BEGIN //! Conversion to `char const*` //! --------------------------- //! A `hana::string` can be converted to a `constexpr` null-delimited - //! string of type `char const*` by using `to<char const*>`. This makes - //! it easy to turn a compile-time string into a runtime string. However, - //! note that this conversion is not an embedding, because `char const*` - //! does not model the same concepts as `hana::string` does. + //! string of type `char const*` by using the `c_str()` method or + //! `hana::to<char const*>`. This makes it easy to turn a compile-time + //! string into a runtime string. However, note that this conversion is + //! not an embedding, because `char const*` does not model the same + //! concepts as `hana::string` does. //! @include example/string/to.cpp //! //! @@ -124,9 +130,16 @@ BOOST_HANA_NAMESPACE_BEGIN template <typename X, typename Y> friend constexpr auto operator>=(X&& x, Y&& y); + //! Performs concatenation; equivalent to `hana::plus` + template <typename X, typename Y> + friend constexpr auto operator+(X&& x, Y&& y); + //! Equivalent to `hana::at` template <typename N> constexpr decltype(auto) operator[](N&& n); + + //! Returns a null-delimited C-style string. + static constexpr char const* c_str(); }; #else template <char ...s> diff --git a/boost/hana/fwd/type.hpp b/boost/hana/fwd/type.hpp index b0a6aec20c..d3390cf5bd 100644 --- a/boost/hana/fwd/type.hpp +++ b/boost/hana/fwd/type.hpp @@ -122,7 +122,7 @@ BOOST_HANA_NAMESPACE_BEGIN //! @relates hana::type //! //! @deprecated - //! The semantics of `decltype_` are can be confusing, and `hana::typeid_` + //! The semantics of `decltype_` can be confusing, and `hana::typeid_` //! should be preferred instead. `decltype_` may be removed in the next //! major version of the library. //! @@ -396,7 +396,7 @@ BOOST_HANA_NAMESPACE_BEGIN //! [1]: http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1430 #ifdef BOOST_HANA_DOXYGEN_INVOKED template <template <typename ...> class F> - constexpr auto template_ = [](basic_type<T>-or-T ...) { + constexpr auto template_ = [](basic_type<T>...) { return hana::type_c<F<T...>>; }; #else @@ -423,7 +423,7 @@ BOOST_HANA_NAMESPACE_BEGIN //! @include example/type/metafunction.cpp #ifdef BOOST_HANA_DOXYGEN_INVOKED template <template <typename ...> class F> - constexpr auto metafunction = [](basic_type<T>-or-T ...) { + constexpr auto metafunction = [](basic_type<T>...) { return hana::type_c<typename F<T...>::type>; }; #else @@ -450,7 +450,7 @@ BOOST_HANA_NAMESPACE_BEGIN //! @include example/type/metafunction_class.cpp #ifdef BOOST_HANA_DOXYGEN_INVOKED template <typename F> - constexpr auto metafunction_class = [](basic_type<T>-or-T ...) { + constexpr auto metafunction_class = [](basic_type<T>...) { return hana::type_c<typename F::template apply<T...>::type>; }; #else @@ -495,7 +495,7 @@ BOOST_HANA_NAMESPACE_BEGIN //! @include example/type/integral.cpp #ifdef BOOST_HANA_DOXYGEN_INVOKED constexpr auto integral = [](auto f) { - return [](basic_type<T>-or-T ...) { + return [](basic_type<T>...) { return decltype(f)::apply<T...>::type{}; }; }; diff --git a/boost/hana/length.hpp b/boost/hana/length.hpp index c7224df9bd..f8493a77c5 100644 --- a/boost/hana/length.hpp +++ b/boost/hana/length.hpp @@ -40,8 +40,8 @@ BOOST_HANA_NAMESPACE_BEGIN namespace detail { struct argn { template <typename ...Xs> - constexpr auto operator()(Xs const& ...) const - { return hana::size_c<sizeof...(Xs)>; } + constexpr hana::size_t<sizeof...(Xs)> operator()(Xs const& ...) const + { return {}; } }; } diff --git a/boost/hana/map.hpp b/boost/hana/map.hpp index 4aecb68482..3161d9b777 100644 --- a/boost/hana/map.hpp +++ b/boost/hana/map.hpp @@ -53,6 +53,7 @@ Distributed under the Boost Software License, Version 1.0. #include <boost/hana/value.hpp> #include <cstddef> +#include <type_traits> #include <utility> @@ -71,33 +72,39 @@ BOOST_HANA_NAMESPACE_BEGIN // map ////////////////////////////////////////////////////////////////////////// //! @cond - template <typename HashTable, typename Storage> - struct map - : detail::searchable_operators<map<HashTable, Storage>> - , detail::operators::adl<map<HashTable, Storage>> - { - using hash_table_type = HashTable; - using storage_type = Storage; - - Storage storage; - - using hana_tag = map_tag; - - explicit constexpr map(Storage const& xs) - : storage(xs) - { } - - explicit constexpr map(Storage&& xs) - : storage(static_cast<Storage&&>(xs)) - { } - - constexpr map() = default; - constexpr map(map const& other) = default; - constexpr map(map&& other) = default; - }; - //! @endcond - namespace detail { + template <typename HashTable, typename Storage> + struct map_impl + : detail::searchable_operators<map_impl<HashTable, Storage>> + , detail::operators::adl<map_impl<HashTable, Storage>> + { + using hash_table_type = HashTable; + using storage_type = Storage; + + Storage storage; + + using hana_tag = map_tag; + + template <typename ...P, typename = typename std::enable_if< + std::is_same< + Storage, + hana::basic_tuple<typename detail::decay<P>::type...> + >::value + >::type> + explicit constexpr map_impl(P&& ...pairs) + : storage{static_cast<P&&>(pairs)...} + { } + + explicit constexpr map_impl(Storage&& xs) + : storage(static_cast<Storage&&>(xs)) + { } + + constexpr map_impl() = default; + constexpr map_impl(map_impl const& other) = default; + constexpr map_impl(map_impl&& other) = default; + }; + //! @endcond + template <typename Storage> struct KeyAtIndex { template <std::size_t i> @@ -117,12 +124,12 @@ BOOST_HANA_NAMESPACE_BEGIN "hana::make_map(pairs...) requires all the 'pairs' to be Products"); static_assert(detail::fast_and< - Comparable<decltype(hana::first(pairs))>::value... + hana::Comparable<decltype(hana::first(pairs))>::value... >::value, "hana::make_map(pairs...) requires all the keys to be Comparable"); static_assert(detail::fast_and< - Constant< + hana::Constant< decltype(hana::equal(hana::first(pairs), hana::first(pairs))) >::value... >::value, @@ -144,9 +151,9 @@ BOOST_HANA_NAMESPACE_BEGIN detail::KeyAtIndex<Storage>::template apply, sizeof...(Pairs) >::type; - return map<HashTable, Storage>( + return detail::map_impl<HashTable, Storage>{ hana::make_basic_tuple(static_cast<Pairs&&>(pairs)...) - ); + }; } }; @@ -189,7 +196,7 @@ BOOST_HANA_NAMESPACE_BEGIN using NewStorage = decltype( hana::append(static_cast<Map&&>(map).storage, static_cast<Pair&&>(pair)) ); - return hana::map<NewHashTable, NewStorage>( + return detail::map_impl<NewHashTable, NewStorage>( hana::append(static_cast<Map&&>(map).storage, static_cast<Pair&&>(pair)) ); } diff --git a/boost/hana/string.hpp b/boost/hana/string.hpp index 836a92be6a..a1b97d2cbb 100644 --- a/boost/hana/string.hpp +++ b/boost/hana/string.hpp @@ -32,7 +32,9 @@ Distributed under the Boost Software License, Version 1.0. #include <boost/hana/fwd/is_empty.hpp> #include <boost/hana/fwd/length.hpp> #include <boost/hana/fwd/less.hpp> +#include <boost/hana/fwd/plus.hpp> #include <boost/hana/fwd/unpack.hpp> +#include <boost/hana/fwd/zero.hpp> #include <boost/hana/if.hpp> #include <boost/hana/integral_constant.hpp> #include <boost/hana/optional.hpp> @@ -48,11 +50,20 @@ BOOST_HANA_NAMESPACE_BEGIN // string<> ////////////////////////////////////////////////////////////////////////// //! @cond + namespace detail { + template <char ...s> + constexpr char const string_storage[sizeof...(s) + 1] = {s..., '\0'}; + } + template <char ...s> struct string : detail::operators::adl<string<s...>> , detail::iterable_operators<string<s...>> - { }; + { + static constexpr char const* c_str() { + return &detail::string_storage<s...>[0]; + } + }; //! @endcond template <char ...s> @@ -132,16 +143,10 @@ BOOST_HANA_NAMESPACE_BEGIN template <> struct to_impl<char const*, string_tag> { template <char ...c> - static constexpr char const c_string[sizeof...(c) + 1] = {c..., '\0'}; - - template <char ...c> static constexpr char const* apply(string<c...> const&) - { return c_string<c...>; } + { return string<c...>::c_str(); } }; - template <char ...c> - constexpr char const to_impl<char const*, string_tag>::c_string[sizeof...(c) + 1]; - ////////////////////////////////////////////////////////////////////////// // Comparable ////////////////////////////////////////////////////////////////////////// @@ -175,6 +180,30 @@ BOOST_HANA_NAMESPACE_BEGIN }; ////////////////////////////////////////////////////////////////////////// + // Monoid + ////////////////////////////////////////////////////////////////////////// + template <> + struct plus_impl<string_tag, string_tag> { + template <char ...s1, char ...s2> + static constexpr auto + apply(string<s1...> const&, string<s2...> const&) { + return string<s1..., s2...>{}; + } + }; + + template <> + struct zero_impl<string_tag> { + static constexpr auto apply() { + return string<>{}; + } + }; + + template <char ...s1, char ...s2> + constexpr auto operator+(string<s1...> const&, string<s2...> const&) { + return hana::string<s1..., s2...>{}; + } + + ////////////////////////////////////////////////////////////////////////// // Foldable ////////////////////////////////////////////////////////////////////////// template <> diff --git a/boost/hana/version.hpp b/boost/hana/version.hpp index b8481658bd..33b30eddfc 100644 --- a/boost/hana/version.hpp +++ b/boost/hana/version.hpp @@ -28,7 +28,7 @@ Distributed under the Boost Software License, Version 1.0. //! @ingroup group-config //! Macro expanding to the patch level of the library, i.e. the `z` in `x.y.z`. -#define BOOST_HANA_PATCH_VERSION 1 +#define BOOST_HANA_PATCH_VERSION 2 //! @ingroup group-config //! Macro expanding to the full version of the library, in hexadecimal |