mirror of
https://github.com/boostorg/hana.git
synced 2026-07-22 13:33:54 +00:00
Merging 'develop' into 'master' for 1.7.0
This commit is contained in:
+3
-8
@@ -1,9 +1,4 @@
|
||||
Release notes for Hana 1.6.1
|
||||
Release notes for Hana 1.7.0
|
||||
============================
|
||||
|
||||
- Official support for Xcode 6, 7 and 8, 9, 10 and LLVM Clang 3.5, 3.6, 3.7,
|
||||
and 3.8 has has been dropped. The library should still work with these
|
||||
compilers, however they are not being tested regularly anymore, so they are
|
||||
not officially supported.
|
||||
- The `hana::traits::result_of` trait has been removed. Since `std::result_of`
|
||||
has been removed from the Standard in C++20, users should move away from it.
|
||||
- Disable the definition of traits::is_pod in C++20 and later, due to its
|
||||
deprecation.
|
||||
|
||||
+31
-31
@@ -3576,41 +3576,41 @@ in pseudo-code, the actual implementation sometimes being slightly hard to
|
||||
understand. This section defines terms used in the reference and in the
|
||||
pseudo-code used to describe some functions.
|
||||
|
||||
@anchor tutorial-glossary-forwarded
|
||||
#### `forwarded(x)`
|
||||
Means that the object is forwarded optimally. This means that if `x` is a
|
||||
parameter, it is `std::forward`ed, and if it is a captured variable, it is
|
||||
moved from whenever the enclosing lambda is an rvalue.
|
||||
- @anchor tutorial-glossary-forwarded `forwarded(x)`
|
||||
|
||||
Also note that when `x` can be moved from, the statement `return forwarded(x);`
|
||||
in a function with `decltype(auto)` does not mean that an rvalue reference to
|
||||
`x` will be returned, which would create a dangling reference. Rather, it
|
||||
means that `x` is returned by value, the value being constructed with the
|
||||
`std::forward`ed `x`.
|
||||
Means that the object is forwarded optimally. This means that if `x` is a
|
||||
parameter, it is `std::forward`ed, and if it is a captured variable, it is
|
||||
moved from whenever the enclosing lambda is an rvalue.
|
||||
|
||||
@anchor tutorial-glossary-perfect_capture
|
||||
#### `perfect-capture`
|
||||
This is used in lambdas to signify that the captured variables are
|
||||
initialized using perfect forwarding, as if `[x(forwarded(x))...]() { }`
|
||||
had been used.
|
||||
Also note that when `x` can be moved from, the statement `return forwarded(x);`
|
||||
in a function with `decltype(auto)` does not mean that an rvalue reference to
|
||||
`x` will be returned, which would create a dangling reference. Rather, it
|
||||
means that `x` is returned by value, the value being constructed with the
|
||||
`std::forward`ed `x`.
|
||||
|
||||
@anchor tutorial-glossary-tag_dispatched
|
||||
#### `tag-dispatched`
|
||||
This means that the documented function uses [tag dispatching]
|
||||
(@ref tutorial-core-tag_dispatching), and hence the exact
|
||||
implementation depends on the model of the concept associated
|
||||
to the function.
|
||||
- @anchor tutorial-glossary-perfect_capture `perfect-capture`
|
||||
|
||||
@anchor tutorial-glossary-implementation_defined
|
||||
#### `implementation-defined`
|
||||
This expresses the fact that the exact implementation of an entity (usually a
|
||||
type) should not be relied upon by users. In particular, this means that one
|
||||
can not assume anything beyond what is written explicitly in the documentation.
|
||||
Usually, the concepts satisfied by an implementation-defined entity will be
|
||||
documented, because one could otherwise do nothing with it. Concretely,
|
||||
assuming too much about an implementation-defined entity will probably
|
||||
not kill you, but it will very probably break your code when you update
|
||||
to a newer version of Hana.
|
||||
This is used in lambdas to signify that the captured variables are
|
||||
initialized using perfect forwarding, as if `[x(forwarded(x))...]() { }`
|
||||
had been used.
|
||||
|
||||
- @anchor tutorial-glossary-tag_dispatched `tag-dispatched`
|
||||
|
||||
This means that the documented function uses [tag dispatching]
|
||||
(@ref tutorial-core-tag_dispatching), and hence the exact
|
||||
implementation depends on the model of the concept associated
|
||||
to the function.
|
||||
|
||||
- @anchor tutorial-glossary-implementation_defined `implementation-defined`
|
||||
|
||||
This expresses the fact that the exact implementation of an entity (usually a
|
||||
type) should not be relied upon by users. In particular, this means that one
|
||||
can not assume anything beyond what is written explicitly in the documentation.
|
||||
Usually, the concepts satisfied by an implementation-defined entity will be
|
||||
documented, because one could otherwise do nothing with it. Concretely,
|
||||
assuming too much about an implementation-defined entity will probably
|
||||
not kill you, but it will very probably break your code when you update
|
||||
to a newer version of Hana.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -15,6 +15,8 @@ Distributed under the Boost Software License, Version 1.0.
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/core/when.hpp>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
|
||||
BOOST_HANA_NAMESPACE_BEGIN
|
||||
//! @cond
|
||||
@@ -44,6 +46,14 @@ BOOST_HANA_NAMESPACE_BEGIN
|
||||
template <typename T> struct tag_of<T const volatile> : tag_of<T> { };
|
||||
template <typename T> struct tag_of<T&> : tag_of<T> { };
|
||||
template <typename T> struct tag_of<T&&> : tag_of<T> { };
|
||||
|
||||
namespace detail {
|
||||
template <typename T>
|
||||
struct has_idempotent_tag
|
||||
: std::is_same<hana::tag_of_t<T>,
|
||||
std::remove_const_t<std::remove_reference_t<T>>>
|
||||
{ };
|
||||
}
|
||||
BOOST_HANA_NAMESPACE_END
|
||||
|
||||
#endif // !BOOST_HANA_CORE_TAG_OF_HPP
|
||||
|
||||
@@ -26,15 +26,23 @@ BOOST_HANA_NAMESPACE_BEGIN namespace detail {
|
||||
|
||||
namespace operators {
|
||||
template <typename X, typename Y, typename = typename std::enable_if<
|
||||
detail::comparable_operators<typename hana::tag_of<X>::type>::value ||
|
||||
detail::comparable_operators<typename hana::tag_of<Y>::type>::value
|
||||
!detail::has_idempotent_tag<X>::value &&
|
||||
!detail::has_idempotent_tag<Y>::value &&
|
||||
(detail::comparable_operators<
|
||||
typename hana::tag_of<X>::type>::value ||
|
||||
detail::comparable_operators<
|
||||
typename hana::tag_of<Y>::type>::value)
|
||||
>::type>
|
||||
constexpr auto operator==(X&& x, Y&& y)
|
||||
{ return hana::equal(static_cast<X&&>(x), static_cast<Y&&>(y)); }
|
||||
|
||||
template <typename X, typename Y, typename = typename std::enable_if<
|
||||
detail::comparable_operators<typename hana::tag_of<X>::type>::value ||
|
||||
detail::comparable_operators<typename hana::tag_of<Y>::type>::value
|
||||
!detail::has_idempotent_tag<X>::value &&
|
||||
!detail::has_idempotent_tag<Y>::value &&
|
||||
(detail::comparable_operators<
|
||||
typename hana::tag_of<X>::type>::value ||
|
||||
detail::comparable_operators<
|
||||
typename hana::tag_of<Y>::type>::value)
|
||||
>::type>
|
||||
constexpr auto operator!=(X&& x, Y&& y)
|
||||
{ return hana::not_equal(static_cast<X&&>(x), static_cast<Y&&>(y)); }
|
||||
|
||||
@@ -191,7 +191,10 @@ BOOST_HANA_NAMESPACE_BEGIN
|
||||
}
|
||||
|
||||
template <typename S>
|
||||
struct equal_impl<S, S, when<hana::Struct<S>::value>> {
|
||||
struct equal_impl<S, S, when<
|
||||
hana::Struct<S>::value &&
|
||||
!detail::EqualityComparable<S, S>::value
|
||||
>> {
|
||||
template <typename X, typename Y>
|
||||
static constexpr auto apply(X const& x, Y const& y) {
|
||||
return hana::all_of(hana::accessors<S>(),
|
||||
|
||||
@@ -67,7 +67,9 @@ BOOST_HANA_NAMESPACE_BEGIN namespace traits {
|
||||
constexpr auto is_trivial = detail::hana_trait<std::is_trivial>{};
|
||||
constexpr auto is_trivially_copyable = detail::hana_trait<std::is_trivially_copyable>{};
|
||||
constexpr auto is_standard_layout = detail::hana_trait<std::is_standard_layout>{};
|
||||
#if __cplusplus < 202002L
|
||||
constexpr auto is_pod = detail::hana_trait<std::is_pod>{};
|
||||
#endif
|
||||
constexpr auto is_literal_type = detail::hana_trait<std::is_literal_type>{};
|
||||
constexpr auto is_empty = detail::hana_trait<std::is_empty>{};
|
||||
constexpr auto is_polymorphic = detail::hana_trait<std::is_polymorphic>{};
|
||||
|
||||
@@ -24,11 +24,11 @@ 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 6
|
||||
#define BOOST_HANA_MINOR_VERSION 7
|
||||
|
||||
//! @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 0
|
||||
|
||||
//! @ingroup group-config
|
||||
//! Macro expanding to the full version of the library, in hexadecimal
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
// Copyright Jason Rice 2020
|
||||
// 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/define_struct.hpp>
|
||||
#include <boost/hana/equal.hpp>
|
||||
#include <boost/hana/members.hpp>
|
||||
#include <boost/hana/not_equal.hpp>
|
||||
namespace hana = boost::hana;
|
||||
|
||||
|
||||
struct SomeStruct {
|
||||
BOOST_HANA_DEFINE_STRUCT(SomeStruct, (int, x));
|
||||
|
||||
constexpr bool operator==(SomeStruct const& other) {
|
||||
return hana::equal(hana::members(*this), hana::members(other));
|
||||
}
|
||||
|
||||
constexpr bool operator!=(SomeStruct const& other) {
|
||||
return hana::not_equal(hana::members(*this), hana::members(other));
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
static_assert(SomeStruct{5} == SomeStruct{5}, "");
|
||||
static_assert(hana::equal(SomeStruct{5}, SomeStruct{5}), "");
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
// Copyright Jason Rice 2020
|
||||
// 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/equal.hpp>
|
||||
#include <boost/hana/not_equal.hpp>
|
||||
#include <boost/hana/tuple.hpp>
|
||||
#include <cassert>
|
||||
namespace hana = boost::hana;
|
||||
|
||||
namespace {
|
||||
template <typename T>
|
||||
struct optional {
|
||||
T t;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
constexpr bool operator==(optional<T> const& o, T const& t) {
|
||||
return o.t == t;
|
||||
}
|
||||
template <typename T>
|
||||
constexpr bool operator==(T const& t, optional<T> const& o) {
|
||||
return o.t == t;
|
||||
}
|
||||
template <typename T>
|
||||
constexpr bool operator!=(optional<T> const& o, T const& t) {
|
||||
return o.t != t;
|
||||
}
|
||||
template <typename T>
|
||||
constexpr bool operator!=(T const& t, optional<T> const& o) {
|
||||
return o.t != t;
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
boost::hana::tuple<int> x{};
|
||||
optional<boost::hana::tuple<int>> attr{x};
|
||||
assert(attr == x); // <-- Kablooey!
|
||||
}
|
||||
@@ -53,7 +53,9 @@ int main() {
|
||||
hana::traits::is_trivial(s);
|
||||
hana::traits::is_trivially_copyable(s);
|
||||
hana::traits::is_standard_layout(s);
|
||||
#if __cplusplus < 202002L
|
||||
hana::traits::is_pod(s);
|
||||
#endif
|
||||
hana::traits::is_literal_type(s);
|
||||
hana::traits::is_empty(s);
|
||||
hana::traits::is_polymorphic(s);
|
||||
|
||||
Reference in New Issue
Block a user