Merging 'develop' into 'master' for 1.7.0

This commit is contained in:
Louis Dionne
2020-09-03 11:41:20 -04:00
10 changed files with 132 additions and 46 deletions
+3 -8
View File
@@ -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
View File
@@ -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.
+10
View File
@@ -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)); }
+4 -1
View File
@@ -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>(),
+2
View File
@@ -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>{};
+2 -2
View File
@@ -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
+27
View File
@@ -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}), "");
}
+39
View File
@@ -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!
}
+2
View File
@@ -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);