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:
@@ -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
55
test/if_/non_copyable.cpp
Normal 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() { }
|
||||
Reference in New Issue
Block a user