Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pfr extension #243

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ target_link_libraries(boost_fusion
Boost::type_traits
Boost::typeof
Boost::utility
Boost::pfr
)
1 change: 1 addition & 0 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ install:
- git submodule init libs/type_traits
- git submodule init libs/typeof
- git submodule init libs/utility
- git submodule init libs/pfr

- git submodule init libs/headers tools/boost_install tools/build
- git submodule update
Expand Down
111 changes: 111 additions & 0 deletions doc/adapted.qbk
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Copyright (C) 2001-2011 Joel de Guzman
Copyright (C) 2006 Dan Marsden
Copyright (C) 2010 Christopher Schmidt
Copyright (C) 2022 Denis Mikhailov

Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
Expand Down Expand Up @@ -1127,6 +1128,116 @@ __adt_attribute_proxy__

[endsect]

[section:adapt_pfr BOOST_FUSION_ADAPT_PFR]

[caution This macro requires at least C++14! Pre C++14 compilers (C++11, C++03...) are not supported.]
[important Also, please read __boost_pfr_lims__ before using this macro. Pay special attention to the SimpleAggregate concept.]

[heading Description]
BOOST_FUSION_ADAPT_PFR is a macro that can be used to generate all the
necessary boilerplate to make an arbitrary struct a model of
__random_access_sequence__.
This macro only works with structures that satisfy the concept of SimpleAggregate.

[heading Synopsis]
BOOST_FUSION_ADAPT_PFR(aggregate_name)

[heading Semantics]

The above macro generates the necessary code to adapt `aggregate_name`
as a model of __random_access_sequence__.

__boost_pfr__ takes responsibility for extracting each of the struct members that
are part of the sequence.

The macro should be used at global scope, and `aggregate_name` should be the fully
namespace qualified name of the struct to be adapted.

[heading Header]

#include <boost/fusion/adapted/pfr/adapt_pfr.hpp>
#include <boost/fusion/include/adapt_pfr.hpp>

[note This macro won't defined by inclusion of 'boost/fusion/adapted.hpp'. ]

[heading Example: BOOST_FUSION_ADAPT_PFR ]
namespace demo
{
struct employee
{
std::string name;
int age;
};
}

// demo::employee is now a Fusion sequence
BOOST_FUSION_ADAPT_PFR(demo::employee)

[heading See also]

__boost_pfr__

[endsect]

[section:adapt_tpl_pfr BOOST_FUSION_ADAPT_TPL_PFR]

[caution This macro requires at least C++14! Pre C++14 compilers (C++11, C++03...) are not supported.]
[important Also, please read __boost_pfr_lims__ before using this macro. Pay special attention to the SimpleAggregate concept.]

[heading Description]
BOOST_FUSION_ADAPT_TPL_PFR is a macro that can be used to generate all the
necessary boilerplate to make an arbitrary template struct a model of
__random_access_sequence__.
This macro only works with structures that satisfy the concept of SimpleAggregate.

[heading Synopsis]
BOOST_FUSION_ADAPT_TPL_PFR(aggregate_name)

[heading Semantics]

The above macro generates the necessary code to adapt `aggregate_name` or an
arbitrary specialization of `aggregate_name` as a model of
__random_access_sequence__.

None of the specializations of `aggregate_name` should have non-type template parameter.
The sequence `(specialization_param0)(specialization_param1)...`
declares the template parameters of the actual specialization of `struct_name`
that is adapted as a fusion sequence.
__boost_pfr__ takes responsibility for extracting each of the struct members that
are part of the sequence.


The macro should be used at global scope, and `aggregate_name` should be the fully
namespace qualified name of the template struct to be adapted.

[heading Header]

#include <boost/fusion/adapted/pfr/adapt_pfr.hpp>
#include <boost/fusion/include/adapt_pfr.hpp>

[note This macro won't defined by inclusion of 'boost/fusion/adapted.hpp'. ]

[heading Example]
namespace demo
{
template<typename Name, typename Age>
struct employee
{
Name name;
Age age;
int employment_timestamp;
};
}

// Any instantiated demo::employee is now a Fusion sequence
BOOST_FUSION_ADAPT_TPL_PFR(demo::employee)

[heading See also]

__boost_pfr__

[endsect]

[section:define_struct BOOST_FUSION_DEFINE_STRUCT]

BOOST_FUSION_DEFINE_STRUCT is a macro that can be used to generate all the
Expand Down
2 changes: 2 additions & 0 deletions doc/fusion.qbk
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@
[def __adapt_tpl_adt__ [link fusion.adapted.adapt_tpl_adt `BOOST_FUSION_ADAPT_TPL_ADT`]]
[def __adapt_assoc_adt__ [link fusion.adapted.adapt_assoc_adt `BOOST_FUSION_ADAPT_ASSOC_ADT`]]
[def __adapt_assoc_tpl_adt__ [link fusion.adapted.adapt_assoc_tpl_adt `BOOST_FUSION_ADAPT_ASSOC_TPL_ADT`]]
[def __adapt_pfr__ [link fusion.adapted.adapt_pfr `BOOST_FUSION_ADAPT_PFR`]]
[def __adapt_tpl_pfr__ [link fusion.adapted.adapt_tpl_pfr `BOOST_FUSION_ADAPT_TPL_PFR`]]
[def __define_struct__ [link fusion.adapted.define_struct `BOOST_FUSION_DEFINE_STRUCT`]]
[def __define_tpl_struct__ [link fusion.adapted.define_tpl_struct `BOOST_FUSION_DEFINE_TPL_STRUCT`]]
[def __define_assoc_struct__ [link fusion.adapted.define_assoc_struct `BOOST_FUSION_DEFINE_ASSOC_STRUCT`]]
Expand Down
2 changes: 2 additions & 0 deletions doc/html/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,8 @@
<dt><span class="section"><a href="fusion/adapted/adapt_tpl_adt.html">BOOST_FUSION_ADAPT_TPL_ADT</a></span></dt>
<dt><span class="section"><a href="fusion/adapted/adapt_assoc_adt.html">BOOST_FUSION_ADAPT_ASSOC_ADT</a></span></dt>
<dt><span class="section"><a href="fusion/adapted/adapt_assoc_tpl_adt.html">BOOST_FUSION_ADAPT_ASSOC_TPL_ADT</a></span></dt>
<dt><span class="section"><a href="fusion/adapted/adapt_pfr.html">BOOST_FUSION_ADAPT_PFR</a></span></dt>
<dt><span class="section"><a href="fusion/adapted/adapt_tpl_pfr.html">BOOST_FUSION_ADAPT_TPL_PFR</a></span></dt>
<dt><span class="section"><a href="fusion/adapted/define_struct.html">BOOST_FUSION_DEFINE_STRUCT</a></span></dt>
<dt><span class="section"><a href="fusion/adapted/define_tpl_struct.html">BOOST_FUSION_DEFINE_TPL_STRUCT</a></span></dt>
<dt><span class="section"><a href="fusion/adapted/define_struct_inline.html">BOOST_FUSION_DEFINE_STRUCT_INLINE</a></span></dt>
Expand Down
8 changes: 8 additions & 0 deletions include/boost/fusion/adapted.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,12 @@
#include <boost/fusion/adapted/std_tuple.hpp>
#endif

// Unfortunately, there is no way to determine the compatibility of the pfr library with the current compiler.
// The "boost/fusion/adapted/pfr.hpp" include has been commented out to ensure backward compatibility
// Please include it manually in your project

// #if !defined(BOOST_FUSION_NO_PFR)
// #include <boost/fusion/adapted/pfr.hpp>
// #endif

#endif
21 changes: 21 additions & 0 deletions include/boost/fusion/adapted/pfr.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*=============================================================================
Copyright (c) 2022 Denis Mikhailov
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_FUSION_ADAPTED_PFR_HPP
#define BOOST_FUSION_ADAPTED_PFR_HPP

#include <boost/fusion/support/config.hpp>
#include <boost/fusion/adapted/pfr/detail/at_impl.hpp>
#include <boost/fusion/adapted/pfr/detail/begin_impl.hpp>
#include <boost/fusion/adapted/pfr/detail/category_of_impl.hpp>
#include <boost/fusion/adapted/pfr/detail/end_impl.hpp>
#include <boost/fusion/adapted/pfr/detail/is_sequence_impl.hpp>
#include <boost/fusion/adapted/pfr/detail/is_view_impl.hpp>
#include <boost/fusion/adapted/pfr/detail/size_impl.hpp>
#include <boost/fusion/adapted/pfr/detail/value_at_impl.hpp>
#include <boost/fusion/adapted/pfr/adapt_pfr.hpp>

#endif
99 changes: 99 additions & 0 deletions include/boost/fusion/adapted/pfr/adapt_pfr.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*=============================================================================
Copyright (c) 2022 Denis Mikhailov
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)
==============================================================================*/

#if !defined(BOOST_FUSION_ADAPTED_STRUCT_ADAPT_PFR_HPP)
#define BOOST_FUSION_ADAPTED_STRUCT_ADAPT_PFR_HPP

#include <boost/fusion/support/config.hpp>
#include <boost/fusion/adapted/pfr/detail/at_impl.hpp>
#include <boost/fusion/adapted/pfr/detail/begin_impl.hpp>
#include <boost/fusion/adapted/pfr/detail/category_of_impl.hpp>
#include <boost/fusion/adapted/pfr/detail/end_impl.hpp>
#include <boost/fusion/adapted/pfr/detail/is_sequence_impl.hpp>
#include <boost/fusion/adapted/pfr/detail/is_view_impl.hpp>
#include <boost/fusion/adapted/pfr/detail/size_impl.hpp>
#include <boost/fusion/adapted/pfr/detail/value_at_impl.hpp>
#include <boost/fusion/support/tag_of_fwd.hpp>

#define BOOST_FUSION_ADAPT_PFR(NAME) \
\
namespace boost { namespace fusion { \
struct pfr_tag; \
struct fusion_sequence_tag; \
\
namespace traits \
{ \
template<> \
struct tag_of<NAME> \
{ \
using type = pfr_tag; \
}; \
template<> \
struct tag_of<NAME const> \
{ \
using type = pfr_tag; \
}; \
} \
}} \
\
namespace boost { namespace mpl \
{ \
template<typename> \
struct sequence_tag; \
\
template<> \
struct sequence_tag<NAME> \
{ \
using type = fusion::fusion_sequence_tag; \
}; \
\
template<> \
struct sequence_tag<NAME const> \
{ \
using type = fusion::fusion_sequence_tag; \
}; \
}}

#define BOOST_FUSION_ADAPT_TPL_PFR(NAME) \
\
namespace boost { namespace fusion { \
struct pfr_tag; \
struct fusion_sequence_tag; \
\
namespace traits \
{ \
template<typename... Args> \
struct tag_of<NAME<Args...>> \
{ \
using type = pfr_tag; \
}; \
template<typename... Args> \
struct tag_of<NAME<Args...> const> \
{ \
using type = pfr_tag; \
}; \
} \
}} \
\
namespace boost { namespace mpl \
{ \
template<typename> \
struct sequence_tag; \
\
template<typename... Args> \
struct sequence_tag<NAME<Args...>> \
{ \
using type = fusion::fusion_sequence_tag; \
}; \
\
template<typename... Args> \
struct sequence_tag<NAME<Args...> const> \
{ \
using type = fusion::fusion_sequence_tag; \
}; \
}}

#endif
43 changes: 43 additions & 0 deletions include/boost/fusion/adapted/pfr/detail/at_impl.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*=============================================================================
Copyright (c) 2022 Denis Mikhailov
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)
==============================================================================*/

#if !defined(BOOST_FUSION_ADAPTED_PFR_DETAIL_AT_IMPL_HPP)
#define BOOST_FUSION_ADAPTED_PFR_DETAIL_AT_IMPL_HPP

#include <boost/fusion/support/config.hpp>
#include <boost/fusion/view/pfr_fields_view.hpp>
#include <boost/fusion/algorithm/auxiliary/pfr_fields.hpp>
#include <boost/fusion/sequence/intrinsic/at.hpp>

namespace boost { namespace fusion
{
struct pfr_tag;

namespace extension
{
template<typename T>
struct at_impl;

template<>
struct at_impl<pfr_tag>
{
template <typename Aggregate, typename N>
struct apply
{
using type = typename result_of::at< pfr_fields_view<Aggregate>, N >::type;

constexpr BOOST_FUSION_GPU_ENABLED
static type
call(Aggregate& seq)
{
return at<N>(pfr_fields(seq));
}
};
};
}
}}

#endif
43 changes: 43 additions & 0 deletions include/boost/fusion/adapted/pfr/detail/begin_impl.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*=============================================================================
Copyright (c) 2022 Denis Mikhailov
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)
==============================================================================*/

#if !defined(BOOST_FUSION_ADAPTED_PFR_DETAIL_BEGIN_IMPL_HPP)
#define BOOST_FUSION_ADAPTED_PFR_DETAIL_BEGIN_IMPL_HPP

#include <boost/fusion/support/config.hpp>
#include <boost/fusion/view/pfr_fields_view.hpp>
#include <boost/fusion/algorithm/auxiliary/pfr_fields.hpp>
#include <boost/fusion/sequence/intrinsic/begin.hpp>

namespace boost { namespace fusion
{
struct pfr_tag;

namespace extension
{
template<typename T>
struct begin_impl;

template <>
struct begin_impl<pfr_tag>
{
template <typename Aggregate>
struct apply
{
using type = typename result_of::begin< pfr_fields_view<Aggregate> >::type;

constexpr BOOST_FUSION_GPU_ENABLED
static type
call(Aggregate& seq)
{
return begin(pfr_fields(seq));
}
};
};
}
}}

#endif