2
0
mirror of https://github.com/boostorg/hana.git synced 2026-01-23 05:32:13 +00:00

[if_] Hold branches by reference instead of moving them in

This commit is contained in:
Louis Dionne
2015-12-16 13:35:18 -05:00
parent 401204d238
commit d93a7c81c3
2 changed files with 65 additions and 5 deletions

View File

@@ -16,7 +16,6 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/config.hpp>
#include <boost/hana/core/dispatch.hpp>
#include <boost/hana/eval_if.hpp>
#include <boost/hana/functional/always.hpp>
BOOST_HANA_NAMESPACE_BEGIN
@@ -39,15 +38,21 @@ BOOST_HANA_NAMESPACE_BEGIN
}
//! @endcond
namespace detail {
template <typename T>
struct hold {
T value;
constexpr T&& operator()() && { return static_cast<T&&>(value); }
};
}
template <typename L, bool condition>
struct if_impl<L, when<condition>> : default_ {
//! @todo By using `always` here, we create a copy of both `t`
//! and `e`, which is not very smart.
template <typename C, typename T, typename E>
static constexpr decltype(auto) apply(C&& c, T&& t, E&& e) {
return hana::eval_if(static_cast<C&&>(c),
hana::always(static_cast<T&&>(t)),
hana::always(static_cast<E&&>(e))
detail::hold<T&&>{static_cast<T&&>(t)},
detail::hold<E&&>{static_cast<E&&>(e)}
);
}
};

55
test/if_/non_copyable.cpp Normal file
View File

@@ -0,0 +1,55 @@
/*
@copyright Louis Dionne 2015
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/bool.hpp>
#include <boost/hana/eval_if.hpp>
#include <boost/hana/fwd/not.hpp>
#include <boost/hana/fwd/while.hpp>
#include <boost/hana/if.hpp>
namespace hana = boost::hana;
// This test makes sure that if_ can be used with non-copyable branches.
template <bool Value>
struct Boolean { };
namespace boost { namespace hana {
template <bool Value>
struct while_impl<Boolean<Value>> {
// Not implemented
};
template <bool Value>
struct not_impl<Boolean<Value>> {
// Not implemented
};
template <bool Value>
struct eval_if_impl<Boolean<Value>> {
template <typename Cond, typename Then, typename Else>
static constexpr decltype(auto) apply(Cond const&, Then&& t, Else&& e) {
return hana::eval_if(hana::bool_c<Value>, static_cast<Then&&>(t),
static_cast<Else&&>(e));
}
};
}}
template <int v>
struct NonCopyable {
static constexpr int value = v;
NonCopyable() = default;
NonCopyable(NonCopyable const&) = delete;
NonCopyable(NonCopyable&&) = default;
NonCopyable& operator=(NonCopyable const&) = delete;
NonCopyable& operator=(NonCopyable&&) = default;
};
static_assert(hana::if_(Boolean<true>{}, NonCopyable<3>{}, NonCopyable<4>{}).value == 3, "");
static_assert(hana::if_(Boolean<false>{}, NonCopyable<3>{}, NonCopyable<4>{}).value == 4, "");
int main() { }