mirror of
https://github.com/boostorg/pfr.git
synced 2026-01-20 16:52:13 +00:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0885412a7d | ||
|
|
86ebac6e0c | ||
|
|
39e9b4c5fe | ||
|
|
01fd8db5b4 |
@@ -49,4 +49,15 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(__has_cpp_attribute)
|
||||
# if __has_cpp_attribute(maybe_unused)
|
||||
# define BOOST_PFR_MAYBE_UNUSED [[maybe_unused]]
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_PFR_MAYBE_UNUSED
|
||||
# define BOOST_PFR_MAYBE_UNUSED
|
||||
#endif
|
||||
|
||||
|
||||
#endif // BOOST_PFR_DETAIL_CONFIG_HPP
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <boost/pfr/detail/make_integer_sequence.hpp>
|
||||
#include <boost/pfr/detail/sequence_tuple.hpp>
|
||||
#include <boost/pfr/detail/rvalue_t.hpp>
|
||||
#include <boost/pfr/detail/unsafe_declval.hpp>
|
||||
|
||||
|
||||
#ifdef __clang__
|
||||
@@ -59,12 +60,6 @@ struct tag {
|
||||
friend auto loophole(tag<T,N>);
|
||||
};
|
||||
|
||||
// For returning non default constructible types. Never used at runtime! GCC's std::declval may not be used in potentionally evaluated contexts, so it does not work here.
|
||||
template <class T> constexpr T& unsafe_declval_like() noexcept {
|
||||
T* ptr = nullptr;
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
// The definitions of friend functions.
|
||||
template <class T, class U, std::size_t N, bool B>
|
||||
struct fn_def_lref {
|
||||
@@ -75,13 +70,13 @@ struct fn_def_lref {
|
||||
// To workaround the issue, we check that the type U is movable, and move it in that case.
|
||||
using no_extents_t = std::remove_all_extents_t<U>;
|
||||
return static_cast< std::conditional_t<std::is_move_constructible<no_extents_t>::value, no_extents_t&&, no_extents_t&> >(
|
||||
boost::pfr::detail::unsafe_declval_like<no_extents_t>()
|
||||
boost::pfr::detail::unsafe_declval<no_extents_t&>()
|
||||
);
|
||||
}
|
||||
};
|
||||
template <class T, class U, std::size_t N, bool B>
|
||||
struct fn_def_rref {
|
||||
friend auto loophole(tag<T,N>) { return std::move(boost::pfr::detail::unsafe_declval_like< std::remove_all_extents_t<U> >()); }
|
||||
friend auto loophole(tag<T,N>) { return std::move(boost::pfr::detail::unsafe_declval< std::remove_all_extents_t<U>& >()); }
|
||||
};
|
||||
|
||||
|
||||
@@ -193,7 +188,7 @@ decltype(auto) tie_or_value(T& val, std::enable_if_t<std::is_enum<std::remove_re
|
||||
}
|
||||
|
||||
template <class T>
|
||||
auto tie_or_value(T& val, std::enable_if_t<std::is_union< std::remove_reference_t<T> >::value>* = 0) noexcept {
|
||||
auto tie_or_value(T& /*val*/, std::enable_if_t<std::is_union< std::remove_reference_t<T> >::value>* = 0) noexcept {
|
||||
static_assert(
|
||||
sizeof(T) && false,
|
||||
"====================> Boost.PFR: For safety reasons it is forbidden to reflect unions. See `Reflection of unions` section in the docs for more info."
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <boost/pfr/detail/config.hpp>
|
||||
#include <boost/pfr/detail/make_integer_sequence.hpp>
|
||||
#include <boost/pfr/detail/size_t_.hpp>
|
||||
#include <boost/pfr/detail/unsafe_declval.hpp>
|
||||
|
||||
#include <climits> // CHAR_BIT
|
||||
#include <type_traits>
|
||||
@@ -28,13 +29,15 @@ namespace boost { namespace pfr { namespace detail {
|
||||
///////////////////// Structure that can be converted to reference to anything
|
||||
struct ubiq_lref_constructor {
|
||||
std::size_t ignore;
|
||||
template <class Type> /*constexpr*/ operator Type&() const noexcept; // Undefined, allows initialization of reference fields (T& and const T&)
|
||||
template <class Type> constexpr operator Type&() const noexcept { // Allows initialization of reference fields (T& and const T&)
|
||||
return detail::unsafe_declval<Type&>();
|
||||
};
|
||||
};
|
||||
|
||||
///////////////////// Structure that can be converted to rvalue reference to anything
|
||||
struct ubiq_rref_constructor {
|
||||
std::size_t ignore;
|
||||
template <class Type> /*constexpr*/ operator Type&&() const noexcept; // Undefined, allows initialization of rvalue reference fields and move-only types
|
||||
template <class Type> /*constexpr*/ operator Type&&() const noexcept {}; // Allows initialization of rvalue reference fields and move-only types
|
||||
};
|
||||
|
||||
|
||||
|
||||
27
include/boost/pfr/detail/unsafe_declval.hpp
Normal file
27
include/boost/pfr/detail/unsafe_declval.hpp
Normal file
@@ -0,0 +1,27 @@
|
||||
// Copyright (c) 2019-2020 Antony Polukhin.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_PFR_DETAIL_UNSAFE_DECLVAL_HPP
|
||||
#define BOOST_PFR_DETAIL_UNSAFE_DECLVAL_HPP
|
||||
|
||||
#include <boost/pfr/detail/config.hpp>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost { namespace pfr { namespace detail {
|
||||
|
||||
// For returning non default constructible types. Never used at runtime! GCC's
|
||||
// std::declval may not be used in potentionally evaluated contexts, so it does not work here.
|
||||
template <class T> constexpr T unsafe_declval() noexcept {
|
||||
typename std::remove_reference<T>::type* ptr = 0;
|
||||
ptr += 42; // killing 'null pointer dereference' heuristics of static analysis tools
|
||||
return static_cast<T>(*ptr);
|
||||
}
|
||||
|
||||
}}} // namespace boost::pfr::detail
|
||||
|
||||
|
||||
#endif // BOOST_PFR_DETAIL_UNSAFE_DECLVAL_HPP
|
||||
|
||||
@@ -54,26 +54,26 @@
|
||||
/// std::size_t hash_value(const T& value) noexcept;
|
||||
/// \endcode
|
||||
|
||||
#define BOOST_PFR_FLAT_FUNCTIONS_FOR(T) \
|
||||
static inline bool operator==(const T& lhs, const T& rhs) noexcept { return ::boost::pfr::flat_equal_to<T>{}(lhs, rhs); } \
|
||||
static inline bool operator!=(const T& lhs, const T& rhs) noexcept { return ::boost::pfr::flat_not_equal<T>{}(lhs, rhs); } \
|
||||
static inline bool operator< (const T& lhs, const T& rhs) noexcept { return ::boost::pfr::flat_less<T>{}(lhs, rhs); } \
|
||||
static inline bool operator> (const T& lhs, const T& rhs) noexcept { return ::boost::pfr::flat_greater<T>{}(lhs, rhs); } \
|
||||
static inline bool operator<=(const T& lhs, const T& rhs) noexcept { return ::boost::pfr::flat_less_equal<T>{}(lhs, rhs); } \
|
||||
static inline bool operator>=(const T& lhs, const T& rhs) noexcept { return ::boost::pfr::flat_greater_equal<T>{}(lhs, rhs); } \
|
||||
template <class Char, class Traits> \
|
||||
static ::std::basic_ostream<Char, Traits>& operator<<(::std::basic_ostream<Char, Traits>& out, const T& value) { \
|
||||
::boost::pfr::flat_write(out, value); \
|
||||
return out; \
|
||||
} \
|
||||
template <class Char, class Traits> \
|
||||
static ::std::basic_istream<Char, Traits>& operator>>(::std::basic_istream<Char, Traits>& in, T& value) { \
|
||||
::boost::pfr::flat_read(in, value); \
|
||||
return in; \
|
||||
} \
|
||||
static inline std::size_t hash_value(const T& v) noexcept { \
|
||||
return ::boost::pfr::flat_hash<T>{}(v); \
|
||||
} \
|
||||
#define BOOST_PFR_FLAT_FUNCTIONS_FOR(T) \
|
||||
BOOST_PFR_MAYBE_UNUSED static inline bool operator==(const T& lhs, const T& rhs) noexcept { return ::boost::pfr::flat_equal_to<T>{}(lhs, rhs); } \
|
||||
BOOST_PFR_MAYBE_UNUSED static inline bool operator!=(const T& lhs, const T& rhs) noexcept { return ::boost::pfr::flat_not_equal<T>{}(lhs, rhs); } \
|
||||
BOOST_PFR_MAYBE_UNUSED static inline bool operator< (const T& lhs, const T& rhs) noexcept { return ::boost::pfr::flat_less<T>{}(lhs, rhs); } \
|
||||
BOOST_PFR_MAYBE_UNUSED static inline bool operator> (const T& lhs, const T& rhs) noexcept { return ::boost::pfr::flat_greater<T>{}(lhs, rhs); } \
|
||||
BOOST_PFR_MAYBE_UNUSED static inline bool operator<=(const T& lhs, const T& rhs) noexcept { return ::boost::pfr::flat_less_equal<T>{}(lhs, rhs); } \
|
||||
BOOST_PFR_MAYBE_UNUSED static inline bool operator>=(const T& lhs, const T& rhs) noexcept { return ::boost::pfr::flat_greater_equal<T>{}(lhs, rhs); } \
|
||||
template <class Char, class Traits> \
|
||||
BOOST_PFR_MAYBE_UNUSED static ::std::basic_ostream<Char, Traits>& operator<<(::std::basic_ostream<Char, Traits>& out, const T& value) { \
|
||||
::boost::pfr::flat_write(out, value); \
|
||||
return out; \
|
||||
} \
|
||||
template <class Char, class Traits> \
|
||||
BOOST_PFR_MAYBE_UNUSED static ::std::basic_istream<Char, Traits>& operator>>(::std::basic_istream<Char, Traits>& in, T& value) { \
|
||||
::boost::pfr::flat_read(in, value); \
|
||||
return in; \
|
||||
} \
|
||||
BOOST_PFR_MAYBE_UNUSED static inline std::size_t hash_value(const T& v) noexcept { \
|
||||
return ::boost::pfr::flat_hash<T>{}(v); \
|
||||
} \
|
||||
/**/
|
||||
|
||||
#endif // BOOST_PFR_FLAT_FUNCTIONS_FOR_HPP
|
||||
|
||||
@@ -52,26 +52,26 @@
|
||||
/// std::size_t hash_value(const T& value);
|
||||
/// \endcode
|
||||
|
||||
#define BOOST_PFR_PRECISE_FUNCTIONS_FOR(T) \
|
||||
static inline bool operator==(const T& lhs, const T& rhs) { return ::boost::pfr::equal_to<T>{}(lhs, rhs); } \
|
||||
static inline bool operator!=(const T& lhs, const T& rhs) { return ::boost::pfr::not_equal<T>{}(lhs, rhs); } \
|
||||
static inline bool operator< (const T& lhs, const T& rhs) { return ::boost::pfr::less<T>{}(lhs, rhs); } \
|
||||
static inline bool operator> (const T& lhs, const T& rhs) { return ::boost::pfr::greater<T>{}(lhs, rhs); } \
|
||||
static inline bool operator<=(const T& lhs, const T& rhs) { return ::boost::pfr::less_equal<T>{}(lhs, rhs); } \
|
||||
static inline bool operator>=(const T& lhs, const T& rhs) { return ::boost::pfr::greater_equal<T>{}(lhs, rhs); } \
|
||||
template <class Char, class Traits> \
|
||||
static ::std::basic_ostream<Char, Traits>& operator<<(::std::basic_ostream<Char, Traits>& out, const T& value) { \
|
||||
::boost::pfr::write(out, value); \
|
||||
return out; \
|
||||
} \
|
||||
template <class Char, class Traits> \
|
||||
static ::std::basic_istream<Char, Traits>& operator>>(::std::basic_istream<Char, Traits>& in, T& value) { \
|
||||
::boost::pfr::read(in, value); \
|
||||
return in; \
|
||||
} \
|
||||
static inline std::size_t hash_value(const T& v) { \
|
||||
return ::boost::pfr::hash<T>{}(v); \
|
||||
} \
|
||||
#define BOOST_PFR_PRECISE_FUNCTIONS_FOR(T) \
|
||||
BOOST_PFR_MAYBE_UNUSED static inline bool operator==(const T& lhs, const T& rhs) { return ::boost::pfr::equal_to<T>{}(lhs, rhs); } \
|
||||
BOOST_PFR_MAYBE_UNUSED static inline bool operator!=(const T& lhs, const T& rhs) { return ::boost::pfr::not_equal<T>{}(lhs, rhs); } \
|
||||
BOOST_PFR_MAYBE_UNUSED static inline bool operator< (const T& lhs, const T& rhs) { return ::boost::pfr::less<T>{}(lhs, rhs); } \
|
||||
BOOST_PFR_MAYBE_UNUSED static inline bool operator> (const T& lhs, const T& rhs) { return ::boost::pfr::greater<T>{}(lhs, rhs); } \
|
||||
BOOST_PFR_MAYBE_UNUSED static inline bool operator<=(const T& lhs, const T& rhs) { return ::boost::pfr::less_equal<T>{}(lhs, rhs); } \
|
||||
BOOST_PFR_MAYBE_UNUSED static inline bool operator>=(const T& lhs, const T& rhs) { return ::boost::pfr::greater_equal<T>{}(lhs, rhs); } \
|
||||
template <class Char, class Traits> \
|
||||
BOOST_PFR_MAYBE_UNUSED static ::std::basic_ostream<Char, Traits>& operator<<(::std::basic_ostream<Char, Traits>& out, const T& value) { \
|
||||
::boost::pfr::write(out, value); \
|
||||
return out; \
|
||||
} \
|
||||
template <class Char, class Traits> \
|
||||
BOOST_PFR_MAYBE_UNUSED static ::std::basic_istream<Char, Traits>& operator>>(::std::basic_istream<Char, Traits>& in, T& value) { \
|
||||
::boost::pfr::read(in, value); \
|
||||
return in; \
|
||||
} \
|
||||
BOOST_PFR_MAYBE_UNUSED static inline std::size_t hash_value(const T& v) { \
|
||||
return ::boost::pfr::hash<T>{}(v); \
|
||||
} \
|
||||
/**/
|
||||
|
||||
#endif // BOOST_PFR_PRECISE_FUNCTIONS_FOR_HPP
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright (C) 2016-2019, Antony Polukhin.
|
||||
# Copyright (C) 2016-2020, Antony Polukhin.
|
||||
#
|
||||
# Use, modification and distribution is subject to the Boost Software License,
|
||||
# Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -143,6 +143,7 @@ test-suite pfr
|
||||
[ run precise/destructuring_tie.cpp : : : $(CLASSIC_PREC_DEF) : precise_destructuring_tie ]
|
||||
[ run precise/error_pfr_c1202.cpp : : : $(CLASSIC_PREC_DEF) : precise_c1202_issue21 ]
|
||||
[ compile-fail precise/non_aggregate.cpp : $(CLASSIC_PREC_DEF) : precise_non_aggregate ]
|
||||
[ run precise/tie_anonymous.cpp : : : $(CLASSIC_PREC_DEF) [ requires cxx17_structured_bindings ] : precise_tie_anonymous ]
|
||||
|
||||
# See "Requirements and Limitations" section of the docs for info on following tests:
|
||||
#[ compile-fail precise/template_constructor.cpp : $(CLASSIC_PREC_DEF) [ requires !cxx17_structured_bindings ] : precise_template_constructor14 ]
|
||||
@@ -176,6 +177,7 @@ test-suite pfr
|
||||
[ run precise/issue30.cpp : : : $(LOOPHOLE_PREC_DEF) : precise_lh_issue30 ]
|
||||
[ run precise/issue33.cpp : : : $(LOOPHOLE_PREC_DEF) : precise_lh_issue33 ]
|
||||
[ compile-fail precise/non_aggregate.cpp : $(LOOPHOLE_PREC_DEF) : precise_lh_non_aggregate ]
|
||||
[ run precise/tie_anonymous.cpp : : : $(LOOPHOLE_PREC_DEF) [ requires cxx17_structured_bindings ] : precise_lh_tie_anonymous ]
|
||||
|
||||
# See "Requirements and Limitations" section of the docs for info on following tests:
|
||||
#[ compile-fail precise/template_constructor.cpp : $(LOOPHOLE_PREC_DEF) [ requires !cxx17_structured_bindings ] : precise_lh_template_constructor14 ]
|
||||
|
||||
@@ -39,10 +39,11 @@ struct comparable_struct {
|
||||
|
||||
BOOST_PFR_TEST_FUNCTIONS_FOR(comparable_struct)
|
||||
|
||||
void test_comparable_struct() {
|
||||
comparable_struct s1 {0, 1, false, 6,7,8,9,10,11};
|
||||
comparable_struct s2 = s1;
|
||||
comparable_struct s3 {0, 1, false, 6,7,8,9,10,11111};
|
||||
template <typename Struct>
|
||||
void test_some_comparable_struct() {
|
||||
Struct s1 {0, 1, false, 6,7,8,9,10,11};
|
||||
Struct s2 = s1;
|
||||
Struct s3 {0, 1, false, 6,7,8,9,10,11111};
|
||||
BOOST_TEST_EQ(s1, s2);
|
||||
BOOST_TEST(s1 <= s2);
|
||||
BOOST_TEST(s1 >= s2);
|
||||
@@ -56,7 +57,7 @@ void test_comparable_struct() {
|
||||
|
||||
std::cout << s1 << std::endl;
|
||||
|
||||
comparable_struct s4;
|
||||
Struct s4;
|
||||
std::stringstream ss;
|
||||
ss.exceptions ( std::ios::failbit);
|
||||
ss << s1;
|
||||
@@ -67,6 +68,10 @@ void test_comparable_struct() {
|
||||
BOOST_TEST_NE(i, j);
|
||||
}
|
||||
|
||||
void test_comparable_struct() {
|
||||
test_some_comparable_struct<comparable_struct>();
|
||||
}
|
||||
|
||||
struct empty { operator std::string() { return "empty{}"; } };
|
||||
BOOST_PFR_TEST_FUNCTIONS_FOR(empty)
|
||||
|
||||
@@ -105,12 +110,58 @@ void test_implicit_conversions() {
|
||||
BOOST_TEST_EQ(ss.str(), "{}"); // Breaks implicit conversion for types marked with BOOST_PFR_TEST_FUNCTIONS_FOR
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
struct anonymous_comparable_struct {
|
||||
int i; short s; bool bl; int a,b,c,d,e,f;
|
||||
};
|
||||
|
||||
BOOST_PFR_TEST_FUNCTIONS_FOR(anonymous_comparable_struct)
|
||||
|
||||
|
||||
struct other_anonymous_struct {
|
||||
anonymous_comparable_struct a,b;
|
||||
};
|
||||
|
||||
BOOST_PFR_TEST_FUNCTIONS_FOR(other_anonymous_struct)
|
||||
|
||||
}
|
||||
|
||||
namespace std {
|
||||
template <>
|
||||
struct hash<anonymous_comparable_struct> {
|
||||
std::size_t operator()(const anonymous_comparable_struct& val) const noexcept {
|
||||
return hash_value(val);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
void test_anonymous_comparable_struct() {
|
||||
test_some_comparable_struct<anonymous_comparable_struct>();
|
||||
}
|
||||
|
||||
void test_nested_anonymous_comparable_struct() {
|
||||
other_anonymous_struct s1{
|
||||
{0, 1, false, 6,7,8,9,10,11},
|
||||
{0, 1, false, 6,7,8,9,10,11},
|
||||
};
|
||||
auto s2 = s1;
|
||||
|
||||
BOOST_TEST_EQ(s1, s2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main() {
|
||||
test_comparable_struct();
|
||||
test_empty_struct();
|
||||
test_with_contatiners<std::less<>>();
|
||||
test_with_contatiners<std::greater<>>();
|
||||
test_implicit_conversions();
|
||||
test_anonymous_comparable_struct();
|
||||
test_nested_anonymous_comparable_struct();
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2018 Antony Polukhin
|
||||
// Copyright (c) 2018-2020 Antony Polukhin
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@@ -122,7 +122,5 @@ void test_counts_on_multiple_chars() {
|
||||
|
||||
int main() {
|
||||
test_counts_on_multiple_chars< BOOST_PFR_RUN_TEST_ON >();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ struct non_default_constructible {
|
||||
T val_;
|
||||
|
||||
non_default_constructible() = delete;
|
||||
template <class U> non_default_constructible(U&& v){}
|
||||
template <class U> non_default_constructible(U&& /*v*/){}
|
||||
};
|
||||
|
||||
struct Foo {
|
||||
|
||||
@@ -11,7 +11,7 @@ struct optional_like {
|
||||
T val_;
|
||||
|
||||
optional_like() = default;
|
||||
template <class U> optional_like(U&& v){}
|
||||
template <class U> optional_like(U&& /*v*/){}
|
||||
};
|
||||
|
||||
struct Foo {
|
||||
|
||||
94
test/precise/tie_anonymous.cpp
Normal file
94
test/precise/tie_anonymous.cpp
Normal file
@@ -0,0 +1,94 @@
|
||||
// Copyright (c) 2020 Antony Polukhin
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
#include <boost/pfr/precise/ops.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
#if defined(__has_include)
|
||||
# if __has_include(<optional>)
|
||||
# include <optional>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
namespace some {
|
||||
struct struct1{ int i; };
|
||||
struct struct2{ int i; };
|
||||
}
|
||||
|
||||
namespace testing {
|
||||
|
||||
namespace {
|
||||
|
||||
#ifdef __cpp_lib_optional
|
||||
struct anon_with_optional {
|
||||
std::string a;
|
||||
std::optional<some::struct1> b;
|
||||
std::optional<some::struct2> c;
|
||||
|
||||
};
|
||||
|
||||
struct other_anon_with_optional {
|
||||
std::string a;
|
||||
int b;
|
||||
std::optional<anon_with_optional> c;
|
||||
std::optional<some::struct2> d;
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
struct other_anon {
|
||||
int data;
|
||||
};
|
||||
|
||||
struct anon {
|
||||
other_anon a;
|
||||
other_anon b;
|
||||
};
|
||||
|
||||
void test_in_anon_ns() {
|
||||
anon x{{1}, {2}};
|
||||
|
||||
auto v = boost::pfr::structure_tie(x);
|
||||
|
||||
BOOST_TEST_EQ(std::get<0>(v).data, 1);
|
||||
BOOST_TEST_EQ(std::get<1>(v).data, 2);
|
||||
|
||||
#ifdef __cpp_lib_optional
|
||||
other_anon_with_optional opt{"test"};
|
||||
auto opt_val = boost::pfr::structure_tie(opt);
|
||||
BOOST_TEST_EQ(std::get<0>(opt_val), "test");
|
||||
#endif
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
void test_in_non_non_ns() {
|
||||
anon x{{1}, {2}};
|
||||
|
||||
auto v = boost::pfr::structure_tie(x);
|
||||
|
||||
BOOST_TEST_EQ(std::get<0>(v).data, 1);
|
||||
BOOST_TEST_EQ(std::get<1>(v).data, 2);
|
||||
|
||||
#ifdef __cpp_lib_optional
|
||||
other_anon_with_optional opt{"test again"};
|
||||
auto opt_val = boost::pfr::structure_tie(opt);
|
||||
BOOST_TEST_EQ(std::get<0>(opt_val), "test again");
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
|
||||
int main() {
|
||||
testing::test_in_anon_ns();
|
||||
testing::test_in_non_non_ns();
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user