diff options
Diffstat (limited to 'boost/hana')
25 files changed, 573 insertions, 299 deletions
diff --git a/boost/hana/at_key.hpp b/boost/hana/at_key.hpp index 74d45d6d56..e4f2e11255 100644 --- a/boost/hana/at_key.hpp +++ b/boost/hana/at_key.hpp @@ -3,6 +3,7 @@ Defines `boost::hana::at_key`. @copyright Louis Dionne 2013-2017 +@copyright Jason Rice 2017 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) */ @@ -24,6 +25,7 @@ Distributed under the Boost Software License, Version 1.0. #include <boost/hana/find_if.hpp> #include <boost/hana/first.hpp> #include <boost/hana/functional/on.hpp> +#include <boost/hana/index_if.hpp> #include <boost/hana/length.hpp> #include <boost/hana/optional.hpp> #include <boost/hana/second.hpp> @@ -67,42 +69,16 @@ BOOST_HANA_NAMESPACE_BEGIN return hana::equal(t, u); } }; - - //! @todo This causes an awful duplication of code with `find_if`. - template <typename Xs, typename Pred, std::size_t i, std::size_t N, bool Done> - struct advance_until; - - template <typename Xs, typename Pred, std::size_t i, std::size_t N> - struct advance_until<Xs, Pred, i, N, false> - : advance_until<Xs, Pred, i + 1, N, static_cast<bool>(detail::decay<decltype( - std::declval<Pred>()(hana::at_c<i>(std::declval<Xs>())) - )>::type::value)> - { }; - - template <typename Xs, typename Pred, std::size_t N> - struct advance_until<Xs, Pred, N, N, false> { - template <typename Ys> - static constexpr auto apply(Ys&&) = delete; - }; - - template <typename Xs, typename Pred, std::size_t i, std::size_t N> - struct advance_until<Xs, Pred, i, N, true> { - template <typename Ys> - static constexpr decltype(auto) apply(Ys&& ys) { - return hana::at_c<i - 1>(static_cast<Ys&&>(ys)); - } - }; } template <typename S> struct at_key_impl<S, when<hana::Sequence<S>::value>> { template <typename Xs, typename Key> - static constexpr decltype(auto) apply(Xs&& xs, Key const&) { - constexpr std::size_t N = decltype(hana::length(xs))::value; - using Pred = at_key_detail::equal_to<Key>; - return at_key_detail::advance_until<Xs&&, Pred, 0, N, false>::apply( - static_cast<Xs&&>(xs) - ); + static constexpr decltype(auto) apply(Xs&& xs, Key const& key) { + using Result = decltype(hana::index_if( + static_cast<Xs&&>(xs), at_key_detail::equal_to<Key>{key})); + + return hana::at(static_cast<Xs&&>(xs), Result{}.value()); } }; diff --git a/boost/hana/basic_tuple.hpp b/boost/hana/basic_tuple.hpp index dbc762fb1b..3e624694e0 100644 --- a/boost/hana/basic_tuple.hpp +++ b/boost/hana/basic_tuple.hpp @@ -21,15 +21,12 @@ Distributed under the Boost Software License, Version 1.0. #include <boost/hana/fwd/core/make.hpp> #include <boost/hana/fwd/core/tag_of.hpp> #include <boost/hana/fwd/drop_front.hpp> +#include <boost/hana/fwd/integral_constant.hpp> #include <boost/hana/fwd/is_empty.hpp> +#include <boost/hana/fwd/length.hpp> #include <boost/hana/fwd/transform.hpp> #include <boost/hana/fwd/unpack.hpp> -#if 0 //! @todo Until we strip down headers, this includes too much -#include <boost/hana/fwd/integral_constant.hpp> -#include <boost/hana/fwd/length.hpp> -#endif - #include <cstddef> #include <type_traits> #include <utility> @@ -244,7 +241,6 @@ BOOST_HANA_NAMESPACE_BEGIN } }; -#if 0 ////////////////////////////////////////////////////////////////////////// // length ////////////////////////////////////////////////////////////////////////// @@ -252,10 +248,9 @@ BOOST_HANA_NAMESPACE_BEGIN struct length_impl<basic_tuple_tag> { template <typename ...Xn> static constexpr auto apply(basic_tuple<Xn...> const&) { - return hana::size_c<sizeof...(Xn)>; + return hana::size_t<sizeof...(Xn)>{}; } }; -#endif BOOST_HANA_NAMESPACE_END #endif // !BOOST_HANA_BASIC_TUPLE_HPP diff --git a/boost/hana/detail/index_if.hpp b/boost/hana/detail/index_if.hpp index 8224f74be8..f643eb76ff 100644 --- a/boost/hana/detail/index_if.hpp +++ b/boost/hana/detail/index_if.hpp @@ -3,6 +3,7 @@ Defines `boost::hana::detail::index_if`. @copyright Louis Dionne 2013-2017 +@copyright Jason Rice 2017 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) */ @@ -11,61 +12,44 @@ Distributed under the Boost Software License, Version 1.0. #define BOOST_HANA_DETAIL_INDEX_IF_HPP #include <boost/hana/config.hpp> -#include <boost/hana/core/when.hpp> +#include <boost/hana/detail/decay.hpp> +#include <boost/hana/integral_constant.hpp> +#include <boost/hana/optional.hpp> #include <cstddef> #include <utility> BOOST_HANA_NAMESPACE_BEGIN namespace detail { - template <typename ...T> - struct pack { - static constexpr std::size_t length = sizeof...(T); + template <std::size_t i, std::size_t N, bool Done> + struct index_if_helper; + + template <std::size_t i, std::size_t N> + struct index_if_helper<i, N, false> { + template <typename Pred, typename X1, typename ...Xs> + using f = typename index_if_helper<i + 1, N, + static_cast<bool>(detail::decay<decltype( + std::declval<Pred>()(std::declval<X1>()))>::type::value) + >::template f<Pred, Xs...>; }; - template <typename T> - struct make_pack; - - template <template <typename...> class Template, typename ...T> - struct make_pack<Template<T...>> { - using type = pack<T...>; - }; - - template <typename T> struct make_pack<T const> : make_pack<T> { }; - template <typename T> struct make_pack<T&> : make_pack<T> { }; - template <typename T> struct make_pack<T&&> : make_pack<T> { }; - - - //! @ingroup group-details - //! Returns the index of the first element of the `pack<>` that satisfies - //! the predicate, or the size of the pack if there is no such element. - //! - //! @note - //! The predicate must return an `IntegralConstant` that can be explicitly - //! converted to `bool`. - template <typename Pred, typename Ts, typename = when<true>> - struct index_if; - - //! @cond - template <typename Pred, typename T, typename ...Ts> - struct index_if<Pred, pack<T, Ts...>, when<static_cast<bool>(decltype( - std::declval<Pred>()(std::declval<T>()) - )::value)>> { - static constexpr std::size_t value = 0; + template <std::size_t N> + struct index_if_helper<N, N, false> { + template <typename ...> + using f = hana::optional<>; }; - template <typename Pred, typename T, typename ...Ts> - struct index_if<Pred, pack<T, Ts...>, when<!static_cast<bool>(decltype( - std::declval<Pred>()(std::declval<T>()) - )::value)>> { - static constexpr std::size_t value = 1 + index_if<Pred, pack<Ts...>>::value; + template <std::size_t i, std::size_t N> + struct index_if_helper<i, N, true> { + template <typename ...> + using f = hana::optional<hana::size_t<i - 1>>; }; - template <typename Pred> - struct index_if<Pred, pack<>> { - static constexpr std::size_t value = 0; + template <typename Pred, typename ...Xs> + struct index_if { + using type = typename index_if_helper<0, sizeof...(Xs), false> + ::template f<Pred, Xs...>; }; - //! @endcond } BOOST_HANA_NAMESPACE_END #endif // !BOOST_HANA_DETAIL_INDEX_IF_HPP diff --git a/boost/hana/detail/struct_macros.erb.hpp b/boost/hana/detail/struct_macros.hpp.erb index 2cdc419593..b3675e82af 100644 --- a/boost/hana/detail/struct_macros.erb.hpp +++ b/boost/hana/detail/struct_macros.hpp.erb @@ -5,7 +5,7 @@ be controlled with the 'MAX_NUMBER_OF_MEMBERS' variable, which can be set when calling ERB to generate the header: - export MAX_NUMBER_OF_MEMBERS=55; erb struct_macros.erb.hpp + export MAX_NUMBER_OF_MEMBERS=55; erb struct_macros.hpp.erb 'MAX_NUMBER_OF_MEMBERS' must be <= 62, otherwise an error is triggered. In case 'MAX_NUMBER_OF_MEMBERS' is not specified, it defaults to 40. diff --git a/boost/hana/detail/variadic/foldl1.hpp b/boost/hana/detail/variadic/foldl1.hpp index 320755f7c7..31388028ab 100644 --- a/boost/hana/detail/variadic/foldl1.hpp +++ b/boost/hana/detail/variadic/foldl1.hpp @@ -15,6 +15,7 @@ Distributed under the Boost Software License, Version 1.0. BOOST_HANA_NAMESPACE_BEGIN namespace detail { namespace variadic { + //! @cond template <unsigned int n, typename = when<true>> struct foldl1_impl; @@ -195,6 +196,7 @@ BOOST_HANA_NAMESPACE_BEGIN namespace detail { namespace variadic { , static_cast<Xn&&>(xn)...); } }; + //! @endcond struct foldl1_t { template <typename F, typename X1, typename ...Xn> diff --git a/boost/hana/detail/variadic/foldr1.hpp b/boost/hana/detail/variadic/foldr1.hpp index 6221451d90..c7323cdaf8 100644 --- a/boost/hana/detail/variadic/foldr1.hpp +++ b/boost/hana/detail/variadic/foldr1.hpp @@ -15,6 +15,7 @@ Distributed under the Boost Software License, Version 1.0. BOOST_HANA_NAMESPACE_BEGIN namespace detail { namespace variadic { + //! @cond template <unsigned int n, typename = when<true>> struct foldr1_impl; @@ -181,6 +182,7 @@ BOOST_HANA_NAMESPACE_BEGIN namespace detail { namespace variadic { foldr1_impl<sizeof...(xn) + 1>::apply(f, static_cast<X56&&>(x56), static_cast<Xn&&>(xn)...)))))))))))))))))))))))))))))))))))))))))))))))))))))))); } }; + //! @endcond struct foldr1_t { template <typename F, typename X1, typename ...Xn> diff --git a/boost/hana/difference.hpp b/boost/hana/difference.hpp index 158e727481..d2e2897d6e 100644 --- a/boost/hana/difference.hpp +++ b/boost/hana/difference.hpp @@ -14,6 +14,7 @@ Distributed under the Boost Software License, Version 1.0. #include <boost/hana/config.hpp> #include <boost/hana/core/dispatch.hpp> +#include <boost/hana/erase_key.hpp> BOOST_HANA_NAMESPACE_BEGIN diff --git a/boost/hana/experimental/view.hpp b/boost/hana/experimental/view.hpp index e9a10b0820..cc2f4c606f 100644 --- a/boost/hana/experimental/view.hpp +++ b/boost/hana/experimental/view.hpp @@ -16,6 +16,7 @@ Distributed under the Boost Software License, Version 1.0. #include <boost/hana/detail/decay.hpp> #include <boost/hana/fold_left.hpp> #include <boost/hana/functional/compose.hpp> +#include <boost/hana/functional/on.hpp> #include <boost/hana/fwd/ap.hpp> #include <boost/hana/fwd/concat.hpp> #include <boost/hana/fwd/drop_front.hpp> diff --git a/boost/hana/ext/std/array.hpp b/boost/hana/ext/std/array.hpp index 0cb513073c..59bc49cf8d 100644 --- a/boost/hana/ext/std/array.hpp +++ b/boost/hana/ext/std/array.hpp @@ -149,13 +149,21 @@ BOOST_HANA_NAMESPACE_BEGIN ////////////////////////////////////////////////////////////////////////// template <> struct less_impl<ext::std::array_tag, ext::std::array_tag> { - template <typename T, typename U> - static constexpr auto apply(std::array<T, 0> const&, std::array<U, 0> const&) - { return hana::false_c; } - template <typename T, std::size_t n, typename U, std::size_t m> static constexpr auto apply(std::array<T, n> const& xs, std::array<U, m> const& ys) { - return detail::lexicographical_compare(&xs[0], &xs[0] + n, &ys[0], &ys[0] + m); + // This logic is more complex than it needs to be because we can't + // use `.begin()` and `.end()`, which are not constexpr in C++14, + // and because `&arr[0]` is UB when the array is empty. + if (xs.empty()) { + return !ys.empty(); + } else { + if (ys.empty()) { + return false; + } else { + return detail::lexicographical_compare(&xs[0], &xs[0] + n, + &ys[0], &ys[0] + m); + } + } } }; BOOST_HANA_NAMESPACE_END diff --git a/boost/hana/find_if.hpp b/boost/hana/find_if.hpp index 3c4e07fcb0..de9c3d3eea 100644 --- a/boost/hana/find_if.hpp +++ b/boost/hana/find_if.hpp @@ -3,6 +3,7 @@ Defines `boost::hana::find_if`. @copyright Louis Dionne 2013-2017 +@copyright Jason Rice 2017 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) */ @@ -17,19 +18,12 @@ Distributed under the Boost Software License, Version 1.0. #include <boost/hana/bool.hpp> #include <boost/hana/concept/iterable.hpp> #include <boost/hana/concept/searchable.hpp> -#include <boost/hana/concept/sequence.hpp> #include <boost/hana/concept/struct.hpp> #include <boost/hana/config.hpp> #include <boost/hana/core/dispatch.hpp> -#include <boost/hana/detail/decay.hpp> -#include <boost/hana/drop_while.hpp> #include <boost/hana/first.hpp> -#include <boost/hana/front.hpp> #include <boost/hana/functional/compose.hpp> -#include <boost/hana/is_empty.hpp> -#include <boost/hana/length.hpp> -#include <boost/hana/not.hpp> -#include <boost/hana/optional.hpp> +#include <boost/hana/index_if.hpp> #include <boost/hana/second.hpp> #include <boost/hana/transform.hpp> @@ -62,68 +56,26 @@ BOOST_HANA_NAMESPACE_BEGIN }; namespace detail { - template <typename Xs, typename Pred, std::size_t i, std::size_t N, bool Done> - struct advance_until; - - template <typename Xs, typename Pred, std::size_t i, std::size_t N> - struct advance_until<Xs, Pred, i, N, false> - : advance_until<Xs, Pred, i + 1, N, static_cast<bool>(detail::decay<decltype( - std::declval<Pred>()(hana::at_c<i>(std::declval<Xs>())) - )>::type::value)> - { }; - - template <typename Xs, typename Pred, std::size_t N> - struct advance_until<Xs, Pred, N, N, false> { - template <typename Ys> - static constexpr auto apply(Ys&&) { - return hana::nothing; - } - }; + template <typename Xs> + struct partial_at { + Xs const& xs; - template <typename Xs, typename Pred, std::size_t i, std::size_t N> - struct advance_until<Xs, Pred, i, N, true> { - template <typename Ys> - static constexpr auto apply(Ys&& ys) { - return hana::just(hana::at_c<i - 1>(static_cast<Ys&&>(ys))); + template <typename I> + constexpr decltype(auto) operator()(I i) const { + return hana::at(xs, i); } }; } - template <typename S> - struct find_if_impl<S, when<Sequence<S>::value>> { - template <typename Xs, typename Pred> - static constexpr auto apply(Xs&& xs, Pred&&) { - constexpr std::size_t N = decltype(hana::length(xs))::value; - return detail::advance_until<Xs&&, Pred&&, 0, N, false>::apply( - static_cast<Xs&&>(xs) - ); - } - }; - - template <typename It> - struct find_if_impl<It, when<hana::Iterable<It>::value && !Sequence<It>::value>> { - template <typename Xs, typename Pred> - static constexpr auto find_if_helper(Xs&& xs, Pred&& pred, hana::true_) { - return hana::just(hana::front( - hana::drop_while(static_cast<Xs&&>(xs), - hana::compose(hana::not_, static_cast<Pred&&>(pred))) - )); - } - - template <typename Xs, typename Pred> - static constexpr auto find_if_helper(Xs&&, Pred&&, hana::false_) { - return hana::nothing; - } - + template <typename Tag> + struct find_if_impl<Tag, when<Iterable<Tag>::value>> { template <typename Xs, typename Pred> static constexpr auto apply(Xs&& xs, Pred&& pred) { - constexpr bool found = !decltype( - hana::is_empty(hana::drop_while(static_cast<Xs&&>(xs), - hana::compose(hana::not_, static_cast<Pred&&>(pred)))) - )::value; - return find_if_impl::find_if_helper(static_cast<Xs&&>(xs), - static_cast<Pred&&>(pred), - hana::bool_<found>{}); + using Result = decltype(hana::index_if( + static_cast<Xs&&>(xs), static_cast<Pred&&>(pred))); + + return hana::transform(Result{}, + detail::partial_at<std::decay_t<Xs>>{static_cast<Xs&&>(xs)}); } }; diff --git a/boost/hana/fwd/adjust_if.hpp b/boost/hana/fwd/adjust_if.hpp index 017ac03972..3042dc72c9 100644 --- a/boost/hana/fwd/adjust_if.hpp +++ b/boost/hana/fwd/adjust_if.hpp @@ -31,7 +31,7 @@ BOOST_HANA_NAMESPACE_BEGIN //! --------- //! Given a `Functor` `F` and a `Logical` `Bool`, the signature is //! \f$ - //! \mathtt{adjust_if} : F(T) \times (T \to Bool) \times (T \to T) \to F(T) + //! \mathtt{adjust\_if} : F(T) \times (T \to Bool) \times (T \to T) \to F(T) //! \f$ //! //! @param xs diff --git a/boost/hana/fwd/core/tag_of.hpp b/boost/hana/fwd/core/tag_of.hpp index bcc4ef8e53..5d490dd717 100644 --- a/boost/hana/fwd/core/tag_of.hpp +++ b/boost/hana/fwd/core/tag_of.hpp @@ -57,7 +57,7 @@ BOOST_HANA_NAMESPACE_BEGIN //! std::is_same< //! typename fusion::traits::tag_of<T>::type, //! fusion::traits::tag_of<fusion::vector<>>::type - //! >{} + //! >::value //! >> { //! using type = BoostFusionVector; //! }; diff --git a/boost/hana/fwd/difference.hpp b/boost/hana/fwd/difference.hpp index 3702f075e0..d96142b5b9 100644 --- a/boost/hana/fwd/difference.hpp +++ b/boost/hana/fwd/difference.hpp @@ -15,50 +15,18 @@ Distributed under the Boost Software License, Version 1.0. BOOST_HANA_NAMESPACE_BEGIN - //! Returns the set-theoretic difference of two sets. - //! @relates hana::set - //! - //! Given two sets `xs` and `ys`, `difference(xs, ys)` is a new set - //! containing all the elements of `xs` that are _not_ contained in `ys`. - //! For any object `x`, the following holds: - //! @code - //! x ^in^ difference(xs, ys) if and only if x ^in^ xs && !(x ^in^ ys) - //! @endcode - //! - //! - //! @note - //! This operation is not commutative, i.e. `difference(xs, ys)` is not - //! necessarily the same as `difference(ys, xs)`. Indeed, consider the - //! case where `xs` is empty and `ys` isn't. Then, `difference(xs, ys)` - //! is empty but `difference(ys, xs)` is equal to `ys`. For the symmetric - //! version of this operation, see `symmetric_difference`. - //! - //! - //! @param xs - //! A set to remove values from. - //! - //! @param ys - //! The set whose values are removed from `xs`. - //! - //! - //! Example - //! ------- - //! @include example/difference.cpp -#ifdef BOOST_HANA_DOXYGEN_INVOKED - constexpr auto difference = [](auto&& xs, auto&& ys) { - return tag-dispatched; - }; -#else + // Note: This function is documented per datatype/concept only. + //! @cond template <typename S, typename = void> struct difference_impl : difference_impl<S, when<true>> { }; + //! @endcond struct difference_t { template <typename Xs, typename Ys> - constexpr auto operator()(Xs&& xs, Ys&& ys) const; + constexpr auto operator()(Xs&&, Ys&&) const; }; constexpr difference_t difference{}; -#endif BOOST_HANA_NAMESPACE_END #endif // !BOOST_HANA_FWD_DIFFERENCE_HPP diff --git a/boost/hana/fwd/index_if.hpp b/boost/hana/fwd/index_if.hpp new file mode 100644 index 0000000000..59f98f59fa --- /dev/null +++ b/boost/hana/fwd/index_if.hpp @@ -0,0 +1,60 @@ +/*! +@file +Forward declares `boost::hana::index_if`. + +@copyright Louis Dionne 2013-2017 +@copyright Jason Rice 2017 +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_INDEX_IF_HPP +#define BOOST_HANA_FWD_INDEX_IF_HPP + +#include <boost/hana/config.hpp> +#include <boost/hana/core/when.hpp> + + +BOOST_HANA_NAMESPACE_BEGIN + //! Finds the value associated to the first key satisfying a predicate. + //! @ingroup group-Iterable + //! + //! Given an `Iterable` structure `xs` and a predicate `pred`, + //! `index_if(xs, pred)` returns a `hana::optional` containing an `IntegralConstant` + //! of the index of the first element that satisfies the predicate or nothing + //! if no element satisfies the predicate. + //! + //! + //! @param xs + //! The structure to be searched. + //! + //! @param predicate + //! A function called as `predicate(x)`, where `x` is an element of the + //! `Iterable` structure and returning whether `x` is the element being + //! searched for. In the current version of the library, the predicate + //! has to return an `IntegralConstant` holding a value that can be + //! converted to `bool`. + //! + //! + //! Example + //! ------- + //! @include example/index_if.cpp +#ifdef BOOST_HANA_DOXYGEN_INVOKED + constexpr auto index_if = [](auto&& xs, auto&& predicate) { + return tag-dispatched; + }; +#else + template <typename S, typename = void> + struct index_if_impl : index_if_impl<S, when<true>> { }; + + struct index_if_t { + template <typename Xs, typename Pred> + constexpr auto operator()(Xs&& xs, Pred&& pred) const; + }; + + constexpr index_if_t index_if{}; +#endif +BOOST_HANA_NAMESPACE_END + +#endif // !BOOST_HANA_FWD_INDEX_IF_HPP + diff --git a/boost/hana/fwd/intersection.hpp b/boost/hana/fwd/intersection.hpp index ec9b1daad2..f289dd03fa 100644 --- a/boost/hana/fwd/intersection.hpp +++ b/boost/hana/fwd/intersection.hpp @@ -15,39 +15,18 @@ Distributed under the Boost Software License, Version 1.0. BOOST_HANA_NAMESPACE_BEGIN - //! Returns the intersection of two sets. - //! @relates hana::set - //! - //! Given two sets `xs` and `ys`, `intersection(xs, ys)` is a new set - //! containing exactly those elements that are present both in `xs` and - //! in `ys`. In other words, the following holds for any object `x`: - //! @code - //! x ^in^ intersection(xs, ys) if and only if x ^in^ xs && x ^in^ ys - //! @endcode - //! - //! - //! @param xs, ys - //! Two sets to intersect. - //! - //! - //! Example - //! ------- - //! @include example/intersection.cpp -#ifdef BOOST_HANA_DOXYGEN_INVOKED - constexpr auto intersection = [](auto&& xs, auto&& ys) { - return tag-dispatched; - }; -#else + // Note: This function is documented per datatype/concept only. + //! @cond template <typename S, typename = void> struct intersection_impl : intersection_impl<S, when<true>> { }; + //! @endcond struct intersection_t { template <typename Xs, typename Ys> - constexpr auto operator()(Xs&& xs, Ys&& ys) const; + constexpr auto operator()(Xs&&, Ys&&) const; }; constexpr intersection_t intersection{}; -#endif BOOST_HANA_NAMESPACE_END #endif // !BOOST_HANA_FWD_INTERSECTION_HPP diff --git a/boost/hana/fwd/map.hpp b/boost/hana/fwd/map.hpp index bff0b012f0..c00f57195f 100644 --- a/boost/hana/fwd/map.hpp +++ b/boost/hana/fwd/map.hpp @@ -255,6 +255,126 @@ BOOST_HANA_NAMESPACE_BEGIN return tag-dispatched; }; #endif + + //! Returns the union of two maps. + //! @relates hana::map + //! + //! Given two maps `xs` and `ys`, `hana::union_(xs, ys)` is a new map + //! containing all the elements of `xs` and all the elements of `ys`, + //! without duplicates. If both `xs` and `ys` contain an element with the + //! same `key`, the one in `ys` is taken. Functionally, + //! `hana::union_(xs, ys)` is equivalent to + //! @code + //! hana::fold_left(xs, ys, hana::insert) + //! @endcode + //! + //! @param xs, ys + //! The two maps to compute the union of. + //! + //! + //! Example + //! ------- + //! @include example/map/union.cpp +#ifdef BOOST_HANA_DOXYGEN_INVOKED + constexpr auto union_ = [](auto&& xs, auto&& ys) { + return tag-dispatched; + }; +#endif + + //! Returns the intersection of two maps. + //! @relates hana::map + //! + //! Given two maps `xs` and `ys`, `intersection(xs, ys)` is a new map + //! containing exactly those (key, value) pairs from xs, for which key + //! is present in `ys`. + //! In other words, the following holds for any object `pair(k, v)`: + //! @code + //! pair(k, v) ^in^ intersection(xs, ys) if and only if (k, v) ^in^ xs && k ^in^ keys(ys) + //! @endcode + //! + //! + //! @note + //! This function is not commutative, i.e. `intersection(xs, ys)` is not + //! necessarily the same as `intersection(ys, xs)`. Indeed, the set of keys + //! in `intersection(xs, ys)` is always the same as the set of keys in + //! `intersection(ys, xs)`, but the value associated to each key may be + //! different. `intersection(xs, ys)` contains values present in `xs`, and + //! `intersection(ys, xs)` contains values present in `ys`. + //! + //! + //! @param xs, ys + //! Two maps to intersect. + //! + //! + //! Example + //! ------- + //! @include example/map/intersection.cpp +#ifdef BOOST_HANA_DOXYGEN_INVOKED + constexpr auto intersection = [](auto&& xs, auto&& ys) { + return tag-dispatched; + }; +#endif + + //! Returns the difference of two maps. + //! @relates hana::map + //! + //! Given two maps `xs` and `ys`, `difference(xs, ys)` is a new map + //! containing exactly those (key, value) pairs from xs, for which key + //! is not present in `keys(ys)`. + //! In other words, the following holds for any object `pair(k, v)`: + //! @code + //! pair(k, v) ^in^ difference(xs, ys) if and only if (k, v) ^in^ xs && k ^not in^ keys(ys) + //! @endcode + //! + //! + //! @note + //! This function is not commutative, i.e. `difference(xs, ys)` is not + //! necessarily the same as `difference(ys, xs)`. + //! Indeed, consider the case where `xs` is empty and `ys` isn't. + //! In that case, `difference(xs, ys)` is empty, but `difference(ys, xs)` + //! is equal to `ys`. + //! For symmetric version of this operation, see `symmetric_difference`. + //! + //! + //! @param xs, ys + //! Two maps to compute the difference of. + //! + //! + //! Example + //! ------- + //! @include example/map/intersection.cpp +#ifdef BOOST_HANA_DOXYGEN_INVOKED + constexpr auto difference = [](auto&& xs, auto&& ys) { + return tag-dispatched; + }; +#endif + + //! Returns the symmetric set-theoretic difference of two maps. + //! @relates hana::map + //! + //! Given two sets `xs` and `ys`, `symmetric_difference(xs, ys)` is a new + //! map containing all the elements of `xs` whose keys are not contained in `keys(ys)`, + //! and all the elements of `ys` whose keys are not contained in `keys(xs)`. The + //! symmetric difference of two maps satisfies the following: + //! @code + //! symmetric_difference(xs, ys) == union_(difference(xs, ys), difference(ys, xs)) + //! @endcode + //! + //! + //! @param xs, ys + //! Two maps to compute the symmetric difference of. + //! + //! + //! Example + //! ------- + //! @include example/map/symmetric_difference.cpp +#ifdef BOOST_HANA_DOXYGEN_INVOKED +constexpr auto symmetric_difference = [](auto&& xs, auto&& ys) { + return tag-dispatched; + }; +#endif + + BOOST_HANA_NAMESPACE_END #endif // !BOOST_HANA_FWD_MAP_HPP diff --git a/boost/hana/fwd/replace_if.hpp b/boost/hana/fwd/replace_if.hpp index e3fe882125..48d5b4c15c 100644 --- a/boost/hana/fwd/replace_if.hpp +++ b/boost/hana/fwd/replace_if.hpp @@ -24,7 +24,7 @@ BOOST_HANA_NAMESPACE_BEGIN //! --------- //! Given `F` a Functor and `Bool` a Logical, the signature is //! \f$ - //! \mathtt{replace_if} : F(T) \times (T \to Bool) \times T \to F(T) + //! \mathtt{replace\_if} : F(T) \times (T \to Bool) \times T \to F(T) //! \f$ //! //! @param xs diff --git a/boost/hana/fwd/set.hpp b/boost/hana/fwd/set.hpp index 55bd72d248..7312854782 100644 --- a/boost/hana/fwd/set.hpp +++ b/boost/hana/fwd/set.hpp @@ -182,9 +182,116 @@ BOOST_HANA_NAMESPACE_BEGIN }; #endif + //! Returns the union of two sets. + //! @relates hana::set + //! + //! Given two sets `xs` and `ys`, `union_(xs, ys)` is a new set containing + //! all the elements of `xs` and all the elements of `ys`, without + //! duplicates. For any object `x`, the following holds: `x` is in + //! `hana::union_(xs, ys)` if and only if `x` is in `xs` or `x` is in `ys`. + //! + //! + //! @param xs, ys + //! Two sets to compute the union of. + //! + //! + //! Example + //! ------- + //! @include example/set/union.cpp +#ifdef BOOST_HANA_DOXYGEN_INVOKED + constexpr auto union_ = [](auto&& xs, auto&& ys) { + return tag-dispatched; + }; +#endif + + //! Returns the intersection of two sets. + //! @relates hana::set + //! + //! Given two sets `xs` and `ys`, `intersection(xs, ys)` is a new set + //! containing exactly those elements that are present both in `xs` and + //! in `ys`. + //! In other words, the following holds for any object `x`: + //! @code + //! x ^in^ intersection(xs, ys) if and only if x ^in^ xs && x ^in^ ys + //! @endcode + //! + //! + //! @param xs, ys + //! Two sets to intersect. + //! + //! + //! Example + //! ------- + //! @include example/set/intersection.cpp +#ifdef BOOST_HANA_DOXYGEN_INVOKED + constexpr auto intersection = [](auto&& xs, auto&& ys) { + return tag-dispatched; + }; +#endif //! Equivalent to `to<set_tag>`; provided for convenience. //! @relates hana::set constexpr auto to_set = to<set_tag>; + + //! Returns the set-theoretic difference of two sets. + //! @relates hana::set + //! + //! Given two sets `xs` and `ys`, `difference(xs, ys)` is a new set + //! containing all the elements of `xs` that are _not_ contained in `ys`. + //! For any object `x`, the following holds: + //! @code + //! x ^in^ difference(xs, ys) if and only if x ^in^ xs && !(x ^in^ ys) + //! @endcode + //! + //! + //! This operation is not commutative, i.e. `difference(xs, ys)` is not + //! necessarily the same as `difference(ys, xs)`. Indeed, consider the + //! case where `xs` is empty and `ys` isn't. Then, `difference(xs, ys)` + //! is empty but `difference(ys, xs)` is equal to `ys`. For the symmetric + //! version of this operation, see `symmetric_difference`. + //! + //! + //! @param xs + //! A set param to remove values from. + //! + //! @param ys + //! The set whose values are removed from `xs`. + //! + //! + //! Example + //! ------- + //! @include example/set/difference.cpp +#ifdef BOOST_HANA_DOXYGEN_INVOKED + constexpr auto difference = [](auto&& xs, auto&& ys) { + return tag-dispatched; +}; +#endif + + //! Returns the symmetric set-theoretic difference of two sets. + //! @relates hana::set + //! + //! Given two sets `xs` and `ys`, `symmetric_difference(xs, ys)` is a new + //! set containing all the elements of `xs` that are not contained in `ys`, + //! and all the elements of `ys` that are not contained in `xs`. The + //! symmetric difference of two sets satisfies the following: + //! @code + //! symmetric_difference(xs, ys) == union_(difference(xs, ys), difference(ys, xs)) + //! @endcode + //! + //! + //! @param xs, ys + //! Two sets to compute the symmetric difference of. + //! + //! + //! Example + //! ------- + //! @include example/set/symmetric_difference.cpp +#ifdef BOOST_HANA_DOXYGEN_INVOKED +constexpr auto symmetric_difference = [](auto&& xs, auto&& ys) { + return tag-dispatched; + }; +#endif + + BOOST_HANA_NAMESPACE_END #endif // !BOOST_HANA_FWD_SET_HPP diff --git a/boost/hana/fwd/symmetric_difference.hpp b/boost/hana/fwd/symmetric_difference.hpp index 2908daaeee..2253f167eb 100644 --- a/boost/hana/fwd/symmetric_difference.hpp +++ b/boost/hana/fwd/symmetric_difference.hpp @@ -15,40 +15,18 @@ Distributed under the Boost Software License, Version 1.0. BOOST_HANA_NAMESPACE_BEGIN - //! Returns the symmetric set-theoretic difference of two sets. - //! @relates hana::set - //! - //! Given two sets `xs` and `ys`, `symmetric_difference(xs, ys)` is a new - //! set containing all the elements of `xs` that are not contained in `ys`, - //! and all the elements of `ys` that are not contained in `xs`. The - //! symmetric difference of two sets satisfies the following: - //! @code - //! symmetric_difference(xs, ys) == union_(difference(xs, ys), difference(ys, xs)) - //! @endcode - //! - //! - //! @param xs, ys - //! Two sets to compute the symmetric difference of. - //! - //! - //! Example - //! ------- - //! @include example/symmetric_difference.cpp -#ifdef BOOST_HANA_DOXYGEN_INVOKED - constexpr auto symmetric_difference = [](auto&& xs, auto&& ys) { - return tag-dispatched; - }; -#else + // Note: This function is documented per datatype/concept only. + //! @cond template <typename S, typename = void> struct symmetric_difference_impl : symmetric_difference_impl<S, when<true>> { }; + //! @endcond struct symmetric_difference_t { template <typename Xs, typename Ys> - constexpr auto operator()(Xs&& xs, Ys&& ys) const; + constexpr auto operator()(Xs&&, Ys&&) const; }; constexpr symmetric_difference_t symmetric_difference{}; -#endif BOOST_HANA_NAMESPACE_END #endif // !BOOST_HANA_FWD_SYMMETRIC_DIFFERENCE_HPP diff --git a/boost/hana/fwd/union.hpp b/boost/hana/fwd/union.hpp index ccf539221f..5775151888 100644 --- a/boost/hana/fwd/union.hpp +++ b/boost/hana/fwd/union.hpp @@ -15,39 +15,18 @@ Distributed under the Boost Software License, Version 1.0. BOOST_HANA_NAMESPACE_BEGIN - //! Returns the union of two sets. - //! @relates hana::set - //! - //! Given two sets `xs` and `ys`, `union_(xs, ys)` is a new set containing - //! all the elements of `xs` and all the elements of `ys`, without - //! duplicates. For any object `x`, the following holds: - //! @code - //! x ^in^ union_(xs, ys) if and only if x ^in^ xs || x ^in^ ys - //! @endcode - //! - //! - //! @param xs, ys - //! Two sets to compute the union of. - //! - //! - //! Example - //! ------- - //! @include example/union.cpp -#ifdef BOOST_HANA_DOXYGEN_INVOKED - constexpr auto union_ = [](auto&& xs, auto&& ys) { - return tag-dispatched; - }; -#else - template <typename S, typename = void> - struct union_impl : union_impl<S, when<true>> { }; + // Note: This function is documented per datatype/concept only. + //! @cond + template <typename T, typename = void> + struct union_impl : union_impl<T, when<true>> { }; + //! @endcond struct union_t { template <typename Xs, typename Ys> - constexpr auto operator()(Xs&& xs, Ys&& ys) const; + constexpr auto operator()(Xs&&, Ys&&) const; }; constexpr union_t union_{}; -#endif BOOST_HANA_NAMESPACE_END #endif // !BOOST_HANA_FWD_UNION_HPP diff --git a/boost/hana/index_if.hpp b/boost/hana/index_if.hpp new file mode 100644 index 0000000000..93ec21c75c --- /dev/null +++ b/boost/hana/index_if.hpp @@ -0,0 +1,105 @@ +/*! +@file +Defines `boost::hana::index_if`. + +@copyright Louis Dionne 2013-2017 +@copyright Jason Rice 2017 +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_INDEX_IF_HPP +#define BOOST_HANA_INDEX_IF_HPP + +#include <boost/hana/concept/foldable.hpp> +#include <boost/hana/concept/iterable.hpp> +#include <boost/hana/config.hpp> +#include <boost/hana/detail/decay.hpp> +#include <boost/hana/detail/index_if.hpp> +#include <boost/hana/fwd/at.hpp> +#include <boost/hana/fwd/basic_tuple.hpp> +#include <boost/hana/fwd/index_if.hpp> +#include <boost/hana/integral_constant.hpp> +#include <boost/hana/length.hpp> +#include <boost/hana/optional.hpp> + +#include <cstddef> +#include <utility> + + +BOOST_HANA_NAMESPACE_BEGIN + //! @cond + template <typename Xs, typename Pred> + constexpr auto index_if_t::operator()(Xs&& xs, Pred&& pred) const { + using S = typename hana::tag_of<Xs>::type; + using IndexIf = BOOST_HANA_DISPATCH_IF(index_if_impl<S>, + hana::Iterable<S>::value + ); + + #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS + static_assert(hana::Iterable<S>::value, + "hana::index_if(xs, pred) requires 'xs' to be a Iterable"); + #endif + + return IndexIf::apply(static_cast<Xs&&>(xs), static_cast<Pred&&>(pred)); + } + //! @endcond + + namespace detail { + template <std::size_t i, std::size_t N, bool Done> + struct iterate_while; + + template <std::size_t i, std::size_t N> + struct iterate_while<i, N, false> { + template <typename Xs, typename Pred> + using f = typename iterate_while<i + 1, N, + static_cast<bool>(detail::decay<decltype( + std::declval<Pred>()( + hana::at(std::declval<Xs>(), hana::size_c<i>)))>::type::value) + >::template f<Xs, Pred>; + }; + + template <std::size_t N> + struct iterate_while<N, N, false> { + template <typename Xs, typename Pred> + using f = hana::optional<>; + }; + + template <std::size_t i, std::size_t N> + struct iterate_while<i, N, true> { + template <typename Xs, typename Pred> + using f = hana::optional<hana::size_t<i - 1>>; + }; + } + + template <typename Tag> + struct index_if_impl<Tag, when<Foldable<Tag>::value>> { + template <typename Xs, typename Pred> + static constexpr auto apply(Xs const& xs, Pred const&) + -> typename detail::iterate_while<0, + decltype(hana::length(xs))::value, false> + ::template f<Xs, Pred> + { return {}; } + }; + + template <typename It> + struct index_if_impl<It, when<!Foldable<It>::value>> { + template <typename Xs, typename Pred> + static constexpr auto apply(Xs const&, Pred const&) + -> typename detail::iterate_while<hana::size_c<0>, + static_cast<std::size_t>(-1), false> + ::template f<Xs, Pred> + { return {}; } + }; + + // basic_tuple is implemented here to solve circular dependency issues. + template <> + struct index_if_impl<basic_tuple_tag> { + template <typename ...Xs, typename Pred> + static constexpr auto apply(basic_tuple<Xs...> const&, Pred const&) + -> typename detail::index_if<Pred, Xs...>::type + { return {}; } + }; +BOOST_HANA_NAMESPACE_END + +#endif // !BOOST_HANA_INDEX_IF_HPP diff --git a/boost/hana/map.hpp b/boost/hana/map.hpp index cccf6cf3b9..8da5012190 100644 --- a/boost/hana/map.hpp +++ b/boost/hana/map.hpp @@ -40,9 +40,12 @@ Distributed under the Boost Software License, Version 1.0. #include <boost/hana/functional/partial.hpp> #include <boost/hana/fwd/any_of.hpp> #include <boost/hana/fwd/at_key.hpp> +#include <boost/hana/fwd/difference.hpp> #include <boost/hana/fwd/erase_key.hpp> +#include <boost/hana/fwd/intersection.hpp> #include <boost/hana/fwd/is_subset.hpp> #include <boost/hana/fwd/keys.hpp> +#include <boost/hana/fwd/union.hpp> #include <boost/hana/insert.hpp> #include <boost/hana/integral_constant.hpp> #include <boost/hana/keys.hpp> @@ -53,6 +56,7 @@ Distributed under the Boost Software License, Version 1.0. #include <boost/hana/unpack.hpp> #include <boost/hana/value.hpp> + #include <cstddef> #include <type_traits> #include <utility> @@ -480,6 +484,71 @@ BOOST_HANA_NAMESPACE_BEGIN }; ////////////////////////////////////////////////////////////////////////// + // union_ + ////////////////////////////////////////////////////////////////////////// + template <> + struct union_impl<map_tag> { + template <typename Xs, typename Ys> + static constexpr auto apply(Xs&& xs, Ys&& ys) { + return hana::fold_left(static_cast<Xs&&>(xs), static_cast<Ys&&>(ys), + hana::insert); + } + }; + + ////////////////////////////////////////////////////////////////////////// + // intersection_ + ////////////////////////////////////////////////////////////////////////// + namespace detail { + template <typename Ys> + struct map_insert_if_contains { + Ys const& ys; + + // Second template param will be pair + // Get its key and check if it exists, if it does, insert key, value pair. + template <typename Result, typename Pair> + static constexpr auto helper(Result&& result, Pair&& pair, hana::true_) { + return hana::insert(static_cast<Result&&>(result), static_cast<Pair&&>(pair)); + } + + template <typename Result, typename Pair> + static constexpr auto helper(Result&& result, Pair&&, hana::false_) { + return static_cast<Result&&>(result); + } + + template <typename Result, typename Pair> + constexpr auto operator()(Result&& result, Pair&& pair) const { + constexpr bool keep = hana::value<decltype(hana::contains(ys, hana::first(pair)))>(); + return map_insert_if_contains::helper(static_cast<Result&&>(result), + static_cast<Pair&&>(pair), + hana::bool_c<keep>); + } + }; + } + + template <> + struct intersection_impl<map_tag> { + template <typename Xs, typename Ys> + static constexpr auto apply(Xs&& xs, Ys const& ys) { + return hana::fold_left(static_cast<Xs&&>(xs), hana::make_map(), + detail::map_insert_if_contains<Ys>{ys}); + } + }; + + ////////////////////////////////////////////////////////////////////////// + // difference + ////////////////////////////////////////////////////////////////////////// + template <> + struct difference_impl<map_tag> { + template <typename Xs, typename Ys> + static constexpr auto apply(Xs&& xs, Ys&& ys) { + return hana::fold_left( + hana::keys(static_cast<Ys&&>(ys)), + static_cast<Xs&&>(xs), + hana::erase_key); + } + }; + + ////////////////////////////////////////////////////////////////////////// // Foldable ////////////////////////////////////////////////////////////////////////// template <> diff --git a/boost/hana/pair.hpp b/boost/hana/pair.hpp index 75cd9e287b..35ff857269 100644 --- a/boost/hana/pair.hpp +++ b/boost/hana/pair.hpp @@ -79,8 +79,8 @@ BOOST_HANA_NAMESPACE_BEGIN BOOST_HANA_TT_IS_CONVERTIBLE(U const&, Second) >::type> constexpr pair(pair<T, U> const& other) - : detail::ebo<detail::pix<0>, First>(detail::ebo_get<detail::pix<0>>(other)) - , detail::ebo<detail::pix<1>, Second>(detail::ebo_get<detail::pix<1>>(other)) + : detail::ebo<detail::pix<0>, First>(hana::first(other)) + , detail::ebo<detail::pix<1>, Second>(hana::second(other)) { } template <typename T, typename U, typename = typename std::enable_if< @@ -90,8 +90,8 @@ BOOST_HANA_NAMESPACE_BEGIN BOOST_HANA_TT_IS_CONVERTIBLE(U&&, Second) >::type> constexpr pair(pair<T, U>&& other) - : detail::ebo<detail::pix<0>, First>(static_cast<T&&>(detail::ebo_get<detail::pix<0>>(other))) - , detail::ebo<detail::pix<1>, Second>(static_cast<U&&>(detail::ebo_get<detail::pix<1>>(other))) + : detail::ebo<detail::pix<0>, First>(hana::first(static_cast<pair<T, U>&&>(other))) + , detail::ebo<detail::pix<1>, Second>(hana::second(static_cast<pair<T, U>&&>(other))) { } @@ -101,8 +101,8 @@ BOOST_HANA_NAMESPACE_BEGIN BOOST_HANA_TT_IS_ASSIGNABLE(Second&, U const&) >::type> constexpr pair& operator=(pair<T, U> const& other) { - detail::ebo_get<detail::pix<0>>(*this) = detail::ebo_get<detail::pix<0>>(other); - detail::ebo_get<detail::pix<1>>(*this) = detail::ebo_get<detail::pix<1>>(other); + hana::first(*this) = hana::first(other); + hana::second(*this) = hana::second(other); return *this; } @@ -111,8 +111,8 @@ BOOST_HANA_NAMESPACE_BEGIN BOOST_HANA_TT_IS_ASSIGNABLE(Second&, U&&) >::type> constexpr pair& operator=(pair<T, U>&& other) { - detail::ebo_get<detail::pix<0>>(*this) = static_cast<T&&>(detail::ebo_get<detail::pix<0>>(other)); - detail::ebo_get<detail::pix<1>>(*this) = static_cast<U&&>(detail::ebo_get<detail::pix<1>>(other)); + hana::first(*this) = hana::first(static_cast<pair<T, U>&&>(other)); + hana::second(*this) = hana::second(static_cast<pair<T, U>&&>(other)); return *this; } diff --git a/boost/hana/tuple.hpp b/boost/hana/tuple.hpp index cab5eaa4d6..3354a84bee 100644 --- a/boost/hana/tuple.hpp +++ b/boost/hana/tuple.hpp @@ -3,6 +3,7 @@ Defines `boost::hana::tuple`. @copyright Louis Dionne 2013-2017 +@copyright Jason Rice 2017 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) */ @@ -27,7 +28,7 @@ Distributed under the Boost Software License, Version 1.0. #include <boost/hana/fwd/at.hpp> #include <boost/hana/fwd/core/make.hpp> #include <boost/hana/fwd/drop_front.hpp> -#include <boost/hana/fwd/find_if.hpp> +#include <boost/hana/fwd/index_if.hpp> #include <boost/hana/fwd/is_empty.hpp> #include <boost/hana/fwd/length.hpp> #include <boost/hana/fwd/optional.hpp> @@ -140,7 +141,7 @@ BOOST_HANA_NAMESPACE_BEGIN // The three following constructors are required to make sure that // the tuple(Yn&&...) constructor is _not_ preferred over the copy // constructor for unary tuples containing a type that is constructible - // from tuple<...>. See test/tuple/trap_construct.cpp + // from tuple<...>. See test/tuple/cnstr.trap.cpp template <typename ...dummy, typename = typename std::enable_if< detail::fast_and<BOOST_HANA_TT_IS_CONSTRUCTIBLE(Xn, Xn const&, dummy...)...>::value >::type> @@ -283,6 +284,14 @@ BOOST_HANA_NAMESPACE_BEGIN return hana::at_c<n>(static_cast<tuple<Xs...>&&>(xs).storage_); } + template <> + struct index_if_impl<tuple_tag> { + template <typename ...Xs, typename Pred> + static constexpr auto apply(tuple<Xs...> const&, Pred const&) + -> typename detail::index_if<Pred, Xs...>::type + { return {}; } + }; + ////////////////////////////////////////////////////////////////////////// // Sequence ////////////////////////////////////////////////////////////////////////// @@ -298,27 +307,6 @@ BOOST_HANA_NAMESPACE_BEGIN tuple<typename detail::decay<Xs>::type...> apply(Xs&& ...xs) { return {static_cast<Xs&&>(xs)...}; } }; - - template <> - struct find_if_impl<tuple_tag> { - template <std::size_t index, typename Xs> - static constexpr auto helper(Xs&&, hana::true_) { - return hana::nothing; - } - - template <std::size_t index, typename Xs> - static constexpr auto helper(Xs&& xs, hana::false_) { - return hana::just(hana::at_c<index>(static_cast<Xs&&>(xs))); - } - - template <typename Xs, typename Pred> - static constexpr auto apply(Xs&& xs, Pred&&) { - using Pack = typename detail::make_pack<Xs>::type; - constexpr std::size_t index = detail::index_if<Pred&&, Pack>::value; - constexpr std::size_t len = Pack::length; - return helper<index>(static_cast<Xs&&>(xs), hana::bool_c<index == len>); - } - }; BOOST_HANA_NAMESPACE_END #endif // !BOOST_HANA_TUPLE_HPP diff --git a/boost/hana/version.hpp b/boost/hana/version.hpp index 2699bfd0e5..160170a51f 100644 --- a/boost/hana/version.hpp +++ b/boost/hana/version.hpp @@ -24,7 +24,7 @@ Distributed under the Boost Software License, Version 1.0. //! @ingroup group-config //! Macro expanding to the minor version of the library, i.e. the `y` in `x.y.z`. -#define BOOST_HANA_MINOR_VERSION 1 +#define BOOST_HANA_MINOR_VERSION 2 //! @ingroup group-config //! Macro expanding to the patch level of the library, i.e. the `z` in `x.y.z`. |