diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:45:59 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:45:59 +0000 |
commit | 19fcec84d8d7d21e796c7624e521b60d28ee21ed (patch) | |
tree | 42d26aa27d1e3f7c0b8bd3fd14e7d7082f5008dc /src/boost/libs/hana/example/misc/ref_tuple.cpp | |
parent | Initial commit. (diff) | |
download | ceph-19fcec84d8d7d21e796c7624e521b60d28ee21ed.tar.xz ceph-19fcec84d8d7d21e796c7624e521b60d28ee21ed.zip |
Adding upstream version 16.2.11+ds.upstream/16.2.11+dsupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/hana/example/misc/ref_tuple.cpp')
-rw-r--r-- | src/boost/libs/hana/example/misc/ref_tuple.cpp | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/src/boost/libs/hana/example/misc/ref_tuple.cpp b/src/boost/libs/hana/example/misc/ref_tuple.cpp new file mode 100644 index 000000000..488925800 --- /dev/null +++ b/src/boost/libs/hana/example/misc/ref_tuple.cpp @@ -0,0 +1,92 @@ +// Copyright Louis Dionne 2013-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) + +#include <boost/hana/assert.hpp> +#include <boost/hana/at.hpp> +#include <boost/hana/core/make.hpp> +#include <boost/hana/core/tag_of.hpp> +#include <boost/hana/drop_front.hpp> +#include <boost/hana/is_empty.hpp> +#include <boost/hana/not.hpp> +#include <boost/hana/tuple.hpp> + +#include <cstddef> +#include <functional> +namespace hana = boost::hana; + + +// A tuple that holds reference_wrappers to its elements, instead of the +// elements themselves. + +struct RefTuple { }; + +template <typename ...T> +struct ref_tuple; + +template <typename ...T> +struct ref_tuple<T&...> { + hana::tuple<std::reference_wrapper<T>...> storage_; +}; + + +namespace boost { namespace hana { + template <typename ...T> + struct tag_of<ref_tuple<T...>> { + using type = RefTuple; + }; + + template <> + struct make_impl<RefTuple> { + template <typename ...T> + static constexpr auto apply(T& ...t) { + return ref_tuple<T&...>{{std::ref(t)...}}; + } + }; + + template <> + struct at_impl<RefTuple> { + template <typename Xs, typename N> + static constexpr decltype(auto) apply(Xs&& xs, N const& n) { + return hana::at(static_cast<Xs&&>(xs).storage_, n).get(); + } + }; + + template <> + struct is_empty_impl<RefTuple> { + template <typename Xs> + static constexpr auto apply(Xs const& xs) { + return hana::is_empty(xs.storage_); + } + }; + + template <> + struct drop_front_impl<RefTuple> { + template <std::size_t n, typename T, typename ...U, std::size_t ...i> + static constexpr auto helper(ref_tuple<T, U...> xs, std::index_sequence<i...>) { + return hana::make<RefTuple>(hana::at_c<n + i>(xs.storage_).get()...); + } + + template <typename ...T, typename N> + static constexpr auto apply(ref_tuple<T...> xs, N const&) { + return helper<N::value>(xs, std::make_index_sequence<( + N::value < sizeof...(T) ? sizeof...(T) - N::value : 0 + )>{}); + } + }; +}} // end namespace boost::hana + + +int main() { + int i = 0, j = 1, k = 2; + + ref_tuple<int&, int&, int&> refs = hana::make<RefTuple>(i, j, k); + hana::at_c<0>(refs) = 3; + BOOST_HANA_RUNTIME_CHECK(i == 3); + + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(refs))); + + ref_tuple<int&, int&> tail = hana::drop_front(refs); + hana::at_c<0>(tail) = 4; + BOOST_HANA_RUNTIME_CHECK(j == 4); +} |