Skip to content

Commit

Permalink
update to Boost.PFR 1.75.0
Browse files Browse the repository at this point in the history
  • Loading branch information
bernhardmgruber committed Feb 3, 2021
1 parent 66ee6fb commit de0bb6c
Show file tree
Hide file tree
Showing 40 changed files with 1,041 additions and 1,737 deletions.
13 changes: 9 additions & 4 deletions include/boost/pfr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,15 @@
#define BOOST_PFR_HPP

/// \file boost/pfr.hpp
/// Includes all the Boost.PFR headers, except \xmlonly<link linkend='header.boost.pfr.flat.global_ops_hpp'>boost/pfr/flat/global_ops.hpp</link>\endxmlonly and \xmlonly<link linkend='header.boost.pfr.precise.global_ops_hpp'>boost/pfr/precise/global_ops.hpp</link>\endxmlonly
/// Includes all the Boost.PFR headers

#include <boost/pfr/precise.hpp>
#include <boost/pfr/flat.hpp>
#include <boost/pfr/core.hpp>
#include <boost/pfr/functions_for.hpp>
#include <boost/pfr/functors.hpp>
#include <boost/pfr/io.hpp>
#include <boost/pfr/io_fields.hpp>
#include <boost/pfr/ops.hpp>
#include <boost/pfr/ops_fields.hpp>
#include <boost/pfr/tuple_size.hpp>

#endif // BOOST_PFR_HPP

121 changes: 85 additions & 36 deletions include/boost/pfr/precise/core.hpp → include/boost/pfr/core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,33 @@
// 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_PRECISE_CORE_HPP
#define BOOST_PFR_PRECISE_CORE_HPP
#ifndef BOOST_PFR_CORE_HPP
#define BOOST_PFR_CORE_HPP
#pragma once

#include <boost/pfr/detail/config.hpp>

#include <type_traits>
#include <utility> // metaprogramming stuff
#include <boost/pfr/detail/core.hpp>

#include <boost/pfr/detail/sequence_tuple.hpp>
#include <boost/pfr/detail/stdtuple.hpp>
#include <boost/pfr/detail/for_each_field_impl.hpp>
#include <boost/pfr/detail/make_integer_sequence.hpp>
#include <boost/pfr/detail/tie_from_structure_tuple.hpp>

#include <boost/pfr/precise/tuple_size.hpp>
#if BOOST_PFR_USE_CPP17
# include <boost/pfr/detail/core17.hpp>
#else
# include <boost/pfr/detail/core14.hpp>
#endif
#include <type_traits>
#include <utility> // metaprogramming stuff

#include <boost/pfr/detail/tie_from_structure_tuple.hpp>
#include <boost/pfr/tuple_size.hpp>

/// \file boost/pfr/core.hpp
/// Contains all the basic tuple-like interfaces \forcedlink{get}, \forcedlink{tuple_size}, \forcedlink{tuple_element_t}, and others.
///
/// \b Synopsis:

namespace boost { namespace pfr {

/// \brief Returns reference or const reference to a field with index `I` in aggregate T.
///
/// \b Requires: C++17 or \flatpod{C++14 flat POD or C++14 with not disabled Loophole}.
/// \brief Returns reference or const reference to a field with index `I` in \aggregate `val`.
///
/// \b Example:
/// \code
Expand All @@ -47,38 +46,52 @@ constexpr decltype(auto) get(const T& val) noexcept {

/// \overload get
template <std::size_t I, class T>
constexpr decltype(auto) get(T& val) noexcept {
constexpr decltype(auto) get(T& val
#if !BOOST_PFR_USE_CPP17
, std::enable_if_t<std::is_assignable<T, T>::value>* = nullptr
#endif
) noexcept {
return detail::sequence_tuple::get<I>( detail::tie_as_tuple(val) );
}

#if !BOOST_PFR_USE_CPP17
/// \overload get
template <std::size_t I, class T>
constexpr auto get(T&, std::enable_if_t<!std::is_assignable<T, T>::value>* = nullptr) noexcept {
static_assert(sizeof(T) && false, "====================> Boost.PFR: Calling boost::pfr::get on non const non assignable type is allowed only in C++17");
return 0;
}
#endif

/// \brief `tuple_element` has a `typedef type-of-a-field-with-index-I-in-aggregate-T type;`
///
/// \b Requires: C++17 or \flatpod{C++14 flat POD or C++14 with not disabled Loophole}.

/// \overload get
template <std::size_t I, class T>
constexpr auto get(T&& val, std::enable_if_t< std::is_rvalue_reference<T&&>::value>* = 0) noexcept {
return std::move(detail::sequence_tuple::get<I>( detail::tie_as_tuple(val) ));
}


/// \brief `tuple_element` has a member typedef `type` that returns the type of a field with index I in \aggregate T.
///
/// \b Example:
/// \code
/// std::vector< boost::pfr::tuple_element<0, my_structure>::type > v;
/// std::vector< boost::pfr::tuple_element<0, my_structure>::type > v;
/// \endcode
template <std::size_t I, class T>
using tuple_element = detail::sequence_tuple::tuple_element<I, decltype( ::boost::pfr::detail::tie_as_tuple(std::declval<T&>()) ) >;


/// \brief Type of a field with index `I` in aggregate `T`.
///
/// \b Requires: C++17 or \flatpod{C++14 flat POD or C++14 with not disabled Loophole}.
/// \brief Type of a field with index `I` in \aggregate `T`.
///
/// \b Example:
/// \code
/// std::vector< boost::pfr::tuple_element_t<0, my_structure> > v;
/// std::vector< boost::pfr::tuple_element_t<0, my_structure> > v;
/// \endcode
template <std::size_t I, class T>
using tuple_element_t = typename tuple_element<I, T>::type;


/// \brief Creates an `std::tuple` from an aggregate T.
///
/// \b Requires: C++17 or \flatpod{C++14 flat POD or C++14 with not disabled Loophole}.
/// \brief Creates a `std::tuple` from fields of an \aggregate `val`.
///
/// \b Example:
/// \code
Expand All @@ -96,33 +109,67 @@ constexpr auto structure_to_tuple(const T& val) noexcept {
}


/// \brief Creates an `std::tuple` with lvalue references to fields of an aggregate T.
/// \brief std::tie` like function that ties fields of a structure.
///
/// \b Requires: C++17 or \flatpod{C++14 flat POD or C++14 with not disabled Loophole}.
/// \returns a `std::tuple` with lvalue and const lvalue references to fields of an \aggregate `val`.
///
/// \b Example:
/// \code
/// void foo(const int&, const short&);
/// struct my_struct { int i, short s; };
///
/// const my_struct const_s{1, 2};
/// std::apply(foo, structure_tie(const_s));
///
/// my_struct s;
/// structure_tie(s) = std::tuple<int, short>{10, 11};
/// assert(s.s == 11);
/// \endcode
template <class T>
constexpr auto structure_tie(T& val) noexcept {
constexpr auto structure_tie(const T& val) noexcept {
return detail::make_conststdtiedtuple_from_tietuple(
detail::tie_as_tuple(const_cast<T&>(val)),
detail::make_index_sequence< tuple_size_v<T> >()
);
}


/// \overload structure_tie
template <class T>
constexpr auto structure_tie(T& val
#if !BOOST_PFR_USE_CPP17
, std::enable_if_t<std::is_assignable<T, T>::value>* = nullptr
#endif
) noexcept {
return detail::make_stdtiedtuple_from_tietuple(
detail::tie_as_tuple(val),
detail::make_index_sequence< tuple_size_v<T> >()
);
}

#if !BOOST_PFR_USE_CPP17
/// \overload structure_tie
template <class T>
constexpr auto structure_tie(T&, std::enable_if_t<!std::is_assignable<T, T>::value>* = nullptr) noexcept {
static_assert(sizeof(T) && false, "====================> Boost.PFR: Calling boost::pfr::structure_tie on non const non assignable type is allowed only in C++17");
return 0;
}
#endif


/// \overload structure_tie
template <class T>
constexpr auto structure_tie(T&&, std::enable_if_t< std::is_rvalue_reference<T&&>::value>* = 0) noexcept {
static_assert(sizeof(T) && false, "====================> Boost.PFR: Calling boost::pfr::structure_tie on rvalue references is forbidden");
return 0;
}

/// Calls `func` for each field of a `value`.
///
/// \b Requires: C++17 or \constexprinit{C++14 constexpr aggregate intializable type}.
///
/// \param func must have one of the following signatures:
/// * any_return_type func(U&& field) // field of value is perfect forwarded to function
/// * any_return_type func(U&& field, std::size_t i)
/// * any_return_type func(U&& value, I i) // Here I is an `std::integral_constant<size_t, field_index>`
/// * any_return_type func(U&& value, I i) // Here I is an `std::integral_constant<size_t, field_index>`
///
/// \param value To each field of this variable will be the `func` applied.
///
Expand All @@ -140,7 +187,7 @@ void for_each_field(T&& value, F&& func) {
::boost::pfr::detail::for_each_field_dispatcher(
value,
[f = std::forward<F>(func)](auto&& t) mutable {
// MSVC related workaround. It's lambdas do not capture constexprs.
// MSVC related workaround. Its lambdas do not capture constexprs.
constexpr std::size_t fields_count_val_in_lambda
= boost::pfr::detail::fields_count<std::remove_reference_t<T>>();

Expand All @@ -155,8 +202,10 @@ void for_each_field(T&& value, F&& func) {
);
}

/// \brief Create a tuple of lvalue references capable of de-structuring
/// assignment from fields of an aggregate T.
/// \brief std::tie-like function that allows assigning to tied values from aggregates.
///
/// \returns an object with lvalue references to `args...`; on assignment of an \aggregate value to that
/// object each field of an aggregate is assigned to the corresponding `args...` reference.
///
/// \b Example:
/// \code
Expand All @@ -174,4 +223,4 @@ constexpr detail::tie_from_structure_tuple<Elements...> tie_from_structure(Eleme

}} // namespace boost::pfr

#endif // BOOST_PFR_PRECISE_CORE_HPP
#endif // BOOST_PFR_CORE_HPP
31 changes: 24 additions & 7 deletions include/boost/pfr/detail/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,48 @@
#define BOOST_PFR_DETAIL_CONFIG_HPP
#pragma once

#include <type_traits> // to get non standard platform macro definitions (__GLIBCXX__ for example)

// Reminder:
// * MSVC++ 1?.? _MSC_VER > 1900 (Visual Studio 2017)
// * MSVC++ 14.2 _MSC_VER == 1927 <- Loophole is known to work (Visual Studio ????)
// * MSVC++ 14.1 _MSC_VER == 1916 <- Loophole is known to NOT work (Visual Studio 2017)
// * MSVC++ 14.0 _MSC_VER == 1900 (Visual Studio 2015)
// * MSVC++ 12.0 _MSC_VER == 1800 (Visual Studio 2013)

#if defined(_MSC_VER)
# if _MSC_VER <= 1900
# error Boost.PFR library requires MSVC with c++17 support (Visual Studio 2017 or later).
# if !defined(_MSVC_LANG) || _MSC_VER <= 1900
# error Boost.PFR library requires more modern MSVC compiler.
# endif
#elif __cplusplus < 201402L
# error Boost.PFR library requires at least C++14.
#endif

#ifndef BOOST_PFR_USE_LOOPHOLE
# if !defined(__clang_major__) || __clang_major__ < 8
# if defined(_MSC_VER)
# if _MSC_VER >= 1927
# define BOOST_PFR_USE_LOOPHOLE 1
# else
# define BOOST_PFR_USE_LOOPHOLE 0
# endif
# elif defined(__clang_major__) && __clang_major__ >= 8
# define BOOST_PFR_USE_LOOPHOLE 0
# else
# define BOOST_PFR_USE_LOOPHOLE 1
# endif
#endif

#ifndef BOOST_PFR_USE_CPP17
# ifdef __cpp_structured_bindings
# define BOOST_PFR_USE_CPP17 1
# elif defined(_MSC_VER)
# warning PFR library supports MSVC compiler only with /std:c++latest or /std:c++17 flag. Assuming that you`ve used it. Define `BOOST_PFR_USE_CPP17` to 1 to suppress this warning.
# define BOOST_PFR_USE_CPP17 1
# elif defined(_MSVC_LANG)
# if _MSVC_LANG >= 201703L
# define BOOST_PFR_USE_CPP17 1
# else
# define BOOST_PFR_USE_CPP17 0
# if !BOOST_PFR_USE_LOOPHOLE
# error Boost.PFR requires /std:c++latest or /std:c++17 flags on your compiler.
# endif
# endif
# else
# define BOOST_PFR_USE_CPP17 0
# endif
Expand Down
24 changes: 24 additions & 0 deletions include/boost/pfr/detail/core.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright (c) 2016-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_CORE_HPP
#define BOOST_PFR_DETAIL_CORE_HPP
#pragma once

#include <boost/pfr/detail/config.hpp>

// Each core provides `boost::pfr::detail::tie_as_tuple` and
// `boost::pfr::detail::for_each_field_dispatcher` functions.
//
// The whole PFR library is build on top of those two functions.
#if BOOST_PFR_USE_CPP17
# include <boost/pfr/detail/core17.hpp>
#elif BOOST_PFR_USE_LOOPHOLE
# include <boost/pfr/detail/core14_loophole.hpp>
#else
# include <boost/pfr/detail/core14_classic.hpp>
#endif

#endif // BOOST_PFR_DETAIL_CORE_HPP
18 changes: 0 additions & 18 deletions include/boost/pfr/detail/core14.hpp

This file was deleted.

14 changes: 3 additions & 11 deletions include/boost/pfr/detail/core14_classic.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,7 @@ constexpr auto internal_tuple_with_same_alignment() noexcept {

static_assert(
std::is_trivial<type>::value && std::is_standard_layout<type>::value,
"====================> Boost.PFR: Type can not be used is flat_ functions, because it's not POD"
"====================> Boost.PFR: Type can not be reflected without Loophole or C++17, because it's not POD"
);
static_assert(!std::is_reference<type>::value, "====================> Boost.PFR: Not applyable");
constexpr auto res = detail::as_flat_tuple_impl<type>(
Expand All @@ -528,7 +528,7 @@ struct ubiq_is_flat_refelectable {

template <class Type>
constexpr operator Type() const noexcept {
is_flat_refelectable = std::is_fundamental<Type>::value;
is_flat_refelectable = std::is_fundamental<std::remove_pointer_t<Type>>::value;
return {};
}
};
Expand Down Expand Up @@ -562,8 +562,6 @@ auto tie_as_flat_tuple(T& lvalue) noexcept {
return boost::pfr::detail::make_flat_tuple_of_references(lvalue, getter, size_t_<0>{}, size_t_<tuple_type::size_v>{});
}

#if !BOOST_PFR_USE_CPP17

template <class T>
auto tie_as_tuple(T& val) noexcept {
static_assert(
Expand All @@ -572,13 +570,11 @@ auto tie_as_tuple(T& val) noexcept {
);
static_assert(
boost::pfr::detail::is_flat_refelectable<T>( detail::make_index_sequence<boost::pfr::detail::fields_count<T>()>{} ),
"====================> Boost.PFR: Not possible in C++14 to represent that type without loosing information. Use boost::pfr::flat_ version, or change type definition, or enable C++17"
"====================> Boost.PFR: Not possible in C++14 to represent that type without loosing information. Change type definition or enable C++17"
);
return boost::pfr::detail::tie_as_flat_tuple(val);
}

#endif // #if !BOOST_PFR_USE_CPP17

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

///////////////////// Structure that can be converted to copy of anything
Expand All @@ -597,8 +593,6 @@ struct ubiq_constructor_constexpr_copy {

/////////////////////

#if !BOOST_PFR_USE_CPP17

template <class T, std::size_t... I>
struct is_constexpr_aggregate_initializable { // TODO: try to fix it
template <T = T{ ubiq_constructor_constexpr_copy{I}... } >
Expand Down Expand Up @@ -697,8 +691,6 @@ void for_each_field_dispatcher(T& t, F&& f, std::index_sequence<I...>) {
);
}

#endif // #if !BOOST_PFR_USE_CPP17

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


Expand Down
Loading

0 comments on commit de0bb6c

Please sign in to comment.