std::tuple like methods for user defined types without any macro or boilerplate code

Overview

Boost.PFR

This is a C++14 library for very basic reflection that gives you access to structure elements by index and provides other std::tuple like methods for user defined types without any macro or boilerplate code.

Boost.PFR is a part of the Boost C++ Libraries. However, Boost.PFR is a header only library that does not depend on Boost. You can just copy the content of the "include" folder from the github into your project, and the library will work fine.

For a version of the library without boost:: namespace see PFR.

Test results

Branches Build Tests coverage More info
Develop: CI Build status Coverage Status details...
Master: CI Build status Coverage Status details...

Latest developer documentation

Motivating Example #0

#include <iostream>
#include <fstream>
#include <string>

#include "boost/pfr.hpp"

struct some_person {
  std::string name;
  unsigned birth_year;
};

int main(int argc, const char* argv[]) {
  some_person val{"Edgar Allan Poe", 1809};

  std::cout << boost::pfr::get<0>(val)                // No macro!
      << " was born in " << boost::pfr::get<1>(val);  // Works with any aggregate initializables!

  if (argc > 1) {
    std::ofstream ofs(argv[1]);
    ofs << boost::pfr::io(val);                       // File now contains: {"Edgar Allan Poe", 1809}
  }
}

Outputs:

Edgar Allan Poe was born in 1809

Motivating Example #1

#include <iostream>
#include "boost/pfr.hpp"

struct my_struct { // no ostream operator defined!
    int i;
    char c;
    double d;
};

int main() {
    my_struct s{100, 'H', 3.141593};
    std::cout << "my_struct has " << boost::pfr::tuple_size<my_struct>::value
        << " fields: " << boost::pfr::io(s) << "\n";
}

Outputs:

my_struct has 3 fields: {100, H, 3.14159}

Motivating Example #2

#include <iostream>
#include "boost/pfr.hpp"

struct my_struct { // no ostream operator defined!
    std::string s;
    int i;
};

int main() {
    my_struct s{{"Das ist fantastisch!"}, 100};
    std::cout << "my_struct has " << boost::pfr::tuple_size<my_struct>::value
        << " fields: " << boost::pfr::io(s) << "\n";
}

Outputs:

my_struct has 2 fields: {"Das ist fantastisch!", 100}

Requirements and Limitations

See docs.

License

Distributed under the Boost Software License, Version 1.0.

Issues
  • Manual type registering/structured bindings might be unnecessary

    Manual type registering/structured bindings might be unnecessary

    It occurred to me that it is possible to implement as_tuple in C++14 very easily using the visitor pattern, with the added benefit of supporting pointers, enums and non primitive types out of the box.

    Following is a rough implementation of the idea, which outputs:

    {42, a, 3.1, (nil), green, hello world!}

    for

    as_tuple(reg{42, 'a', 3.1, nullptr, color::green, "hello world!"}, [](auto&& t) {
        print_tuple(std::forward<decltype(t)>(t));
        std::cout << std::endl;
    });
    

    where

    struct reg {
        int a;
        char b;
        double d;
        void* e;
        color f;
        std::string g;
    };
    

    and

    enum class color {
        red,
        green,
        blue
    };
    
    std::ostream& operator <<(std::ostream& os, color c) {
        switch(c) {
            case color::red:
                os << "red";
                break;
            case color::green:
                os << "green";
                break;
            case color::blue:
                os << "blue";
                break;
        };
    
        return os;
    }
    

    Note: it only works on Clang + libc++ due to the reinterpret_cast to std::tuple.

    #include <tuple>
    #include <cstdint>
    #include <utility>
    #include <iostream>
    #include <type_traits>
    #include <initializer_list>
    
    template<typename...>
    using void_t = void;
    
    template<typename>
    struct type {};
    
    template<std::size_t>
    struct ubiq
    {
        template<typename T>
        operator T() const;
    };
    
    
    template<typename, typename, typename = void>
    struct _size_impl
    {};
    
    template<typename T, std::size_t head, std::size_t... tail>
    struct _size_impl<T, std::index_sequence<head, tail...>,
        void_t<decltype(T{ubiq<head>{}, ubiq<tail>{}...})>
    > :
        std::integral_constant<std::size_t, sizeof...(tail) + 1>
    {};
    
    template<typename T, std::size_t head, std::size_t... tail, typename _>
    struct _size_impl<T, std::index_sequence<head, tail...>, _> :
        _size_impl<T, std::index_sequence<tail...>>
    {};
    
    template<typename T>
    struct _size :
        _size_impl<T, std::make_index_sequence<sizeof(T)>>
    {};
    
    template<typename T>
    using size = typename _size<T>::type;
    
    template<typename F>
    struct deducer
    {
        F f;
    
        template<typename T>
        operator T() const {
            f(type<T>{});
            return {};
        }
    };
    
    template<typename F>
    deducer<std::decay_t<F>> deduce(F&& f) {
        return {std::forward<F>(f)};
    }
    
    template<typename F, typename T, typename... Props>
    auto as_tuple_impl(F&& f, T&& t, type<Props>...)
        -> std::enable_if_t<size<std::decay_t<T>>::value != sizeof...(Props)> {
        std::decay_t<T>{
            Props{}...,
            deduce(
                [&f, &t](auto prop) {
                    as_tuple_impl(
                        std::forward<F>(f),
                        std::forward<T>(t),
                        type<Props>{}...,
                        prop
                    );
                }
            )
        };
    }
    
    template<typename F, typename T, typename... Props>
    auto as_tuple_impl(F&& f, T&& t, type<Props>...)
        -> std::enable_if_t<size<std::decay_t<T>>::value == sizeof...(Props)> {
        std::forward<F>(f)(reinterpret_cast<std::tuple<Props...>&&>(t));
    }
    
    template<typename F, typename T, typename... Props>
    auto as_tuple_impl(F&& f, T& t, type<Props>...)
        -> std::enable_if_t<size<T>::value == sizeof...(Props)> {
        std::forward<F>(f)(reinterpret_cast<std::tuple<Props...>&>(t));
    }
    
    template<typename T, typename F>
    auto as_tuple(T&& t, F&& f) {
        as_tuple_impl(std::forward<F>(f), std::forward<T>(t));
    }
    
    template<typename... R, std::size_t h, std::size_t... t>
    void print_tuple_impl(std::tuple<R...> const& r, std::index_sequence<h, t...>) {
        std::cout << '{' << std::get<h>(r);
        std::initializer_list<int>{
            (void(std::cout << ", " << std::get<t>(r)), 0)...
        };
        std::cout << '}';
    }
    
    template<typename... T>
    void print_tuple(std::tuple<T...> const& t) {
        print_tuple_impl(t, std::index_sequence_for<T...>{});
    }
    
    opened by brunocodutra 14
  • Attempt to factor out cast_to_layout_compatible

    Attempt to factor out cast_to_layout_compatible

    Hi,

    Here's my attempt at implementing the idea I described in issue #12

    I had some issues testing it -- even without my commit, I am on ubuntu 16.04 xenial and I don't have a c++14 standard library on my system, so I don't have some things like std::less<void> and std::greater<void> which are used in some of the tests.

    However, the same set of tests are passing and failing before and after my commit, using gcc 5.4 and clang 4.0, nor do I have new warnings. So I think this commit is at least close to correct.

    (As a minor complaint -- it would be nice if there were a simple script to run the tests. To figure out how to run them locally I had to sort of reverse engineer from the travis.yml file. I guess that the test mechanism relies on the boost repo and so can't be run without cloning boost.)

    I would like to test also on my macbook, and I would also like to do some tests with godbolt to inspect the generated assembly and make sure this is not significantly different in terms of efficiency.

    However, I don't have time to do that stuff until about Thursday, so you might want to hold off until then. I will try to test it with c++14 conforming standard library at that time.


    The commit message describes the changes I made. Basically, where previously we used cast_to_layout_compatible and then make_tuple_of_references, what I tried to do was, generalize make_tuple_of_references so that it takes instead an arbitrary object, together with a getter that can implement get<i> on that object.

    Then, for cases when you needed to apply this to a tuple, there is a sequence_tuple_getter which wraps sequence_tuple::get. And for user-defined structures, there is an offset_based_getter, which takes as template parameters the user-structure S, and the sequence_tuple<T1, T2, ...> generated by using the ubiqs. Assuming that the sequence_tuple is indeed layout compatible with S, the offset_based_getter I believe should optimize to code that is just as good as cast_to_layout_compatible, and I don't think it should violate the standard anywhere. There is some more technical discussion in the commit message.


    Another thing to be considered, now that I think of it, is that maybe the cast_to_layout_compatible should be kept around and enabled by use of a flag -- that way if on some compilers this change causes a regression, people can revert to the old way.

    Cheers, Chris

    opened by garbageslam 12
  • Example does not compile VS C++17

    Example does not compile VS C++17

    The example:

    #include <iostream>
    #include <string>
    #include "boost/pfr/precise.hpp"
    
    struct some_person {
        std::string name;
        unsigned birth_year;
    };
    
    int main() {
        some_person val{"Edgar Allan Poe", 1809};
    
        std::cout << boost::pfr::get<0>(val)                // No macro!
            << " was born in " << boost::pfr::get<1>(val);  // Works with any aggregate initializables!
    }
    

    Does not compile:

    1>a:\cpp\reftest\reftest\ext\include\boost\pfr\detail\fields_count.hpp(209): error C2338: ====================> Boost.PFR: Types with user specified constructors (non-aggregate initializable types) are not supported.
    1>a:\cpp\reftest\reftest\ext\include\boost\pfr\detail\core17_generated.hpp(1036): note: see reference to function template instantiation 'size_t boost::pfr::detail::fields_count<T>(void) noexcept' being compiled
    1>        with
    1>        [
    1>            T=some_person
    1>        ]
    1>a:\cpp\reftest\reftest\ext\include\boost\pfr\precise\core.hpp(50): note: see reference to function template instantiation 'auto boost::pfr::detail::tie_as_tuple<T>(T &) noexcept' being compiled
    1>        with
    1>        [
    1>            T=some_person
    1>        ]
    1>a:\cpp\reftest\reftest\src\main.cpp(62): note: see reference to function template instantiation 'decltype(auto) boost::pfr::get<0,some_person>(T &) noexcept' being compiled
    1>        with
    1>        [
    1>            T=some_person
    1>        ]
    1>a:\cpp\reftest\reftest\ext\include\boost\pfr\detail\fields_count.hpp(214): error C2338: ====================> Boost.PFR: If there's no other failed static asserts then something went wrong. Please report this issue to the github along with the structure you're reflecting.
    1>a:\cpp\reftest\reftest\ext\include\boost\pfr\detail\sequence_tuple.hpp(114): error C2338: ====================> Boost.PFR: Tuple index out of bounds
    1>a:\cpp\reftest\reftest\ext\include\boost\pfr\precise\core.hpp(50): note: see reference to function template instantiation 'decltype(auto) boost::pfr::detail::sequence_tuple::get<0,>(boost::pfr::detail::sequence_tuple::tuple<> &&) noexcept' being compiled
    1>a:\cpp\reftest\reftest\ext\include\boost\pfr\detail\sequence_tuple.hpp(115): error C2672: 'get_impl': no matching overloaded function found
    1>a:\cpp\reftest\reftest\ext\include\boost\pfr\detail\sequence_tuple.hpp(113): error C2784: 'T &boost::pfr::detail::sequence_tuple::get_impl(boost::pfr::detail::sequence_tuple::base_from_member<N,T> &) noexcept': could not deduce template argument for 'boost::pfr::detail::sequence_tuple::base_from_member<0,T> &' from 'boost::pfr::detail::sequence_tuple::tuple<>'
    1>a:\cpp\reftest\reftest\ext\include\boost\pfr\detail\sequence_tuple.hpp(51): note: see declaration of 'boost::pfr::detail::sequence_tuple::get_impl'
    1>a:\cpp\reftest\reftest\src\main.cpp(62): error C2679: binary '<<': no operator found which takes a right-hand operand of type 'void' (or there is no acceptable conversion)
    

    Compiler:

    /JMC /permissive- /MP /GS /W3 /Zc:wchar_t /I"A:\cpp\reftest\reftest\ext\include\" /I"A:\cpp\reftest\\include\" /I"C:\Program Files (x86)\Visual Leak Detector\include" /ZI /Gm- /Od /sdl /Fd"x64\Debug\vc141.pdb" /Zc:inline /fp:precise /D "_MBCS" /errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /MDd /std:c++17 /FC /Fa"x64\Debug\" /EHsc /nologo /Fo"x64\Debug\" /Fp"x64\Debug\reftest.pch" /diagnostics:classic 
    
    bug enhancement 
    opened by simonrenger 9
  • pfr::ops doesn't support unions in PODs

    pfr::ops doesn't support unions in PODs

    First off, I love this library. I find myself writing a lot of binary protocols that support unions. One thing I do to test out my binary parsers/generators, is just sending the instance to operator<< and not having to write a 100+ line function myself, I love this (ehm, Rust has this as well).

    Any ideas on how you could support unions? Maybe just convert to std::tuple<> and print that? I've gotten boost::hana to play nice sometimes but nothing notable. I think if you support unions, lots of C code or legacy C++ could be brought to a new light by just automatically having pfr::ops work.

    Thanks!

    opened by anthonygclark 9
  • C1202 on MSVC, probably on every sizeof(T) >= 256 class

    C1202 on MSVC, probably on every sizeof(T) >= 256 class

    your library is superb! Having that kind of "reflection light" is handy in so many places!

    I was going to make an experimental Config class, which can be reflected for Serialization to file or visualisation etc. At some point my MSVC compiler reports error C1202 when trying to call pfr::for_each_field on that class object. After some investigation it seems to appear when the reflected class reaches 256 Bytes. I.e. I can get this error by either adding more members or by increasing the size of each member.

    The attached example has 2 defines, if you set one of them, MSVC (VS2017 15.6.2) will emit C1202. I hope I didn´t make an error, since I´m not sure if my Cfg Templates do actually fit the requirements. I´m afraid its a compiler limitation w/o workarround... All I can tell is, if it compiles it works as expected. If you are interested to look into this and need more info please let me know. Thanks!

    pfr_C1202.zip

    enhancement 
    opened by andj1210 8
  • CMake support

    CMake support

    At the moment this library does not support clients using CMake. Is there a plan to change that?

    The documentation's You can just copy the content of the "include" folder suggestion is not acceptable.

    Since this is a header-only library with no dependency on other Boost libraries, the lists file to provide support would look trivial.
    I could make a PR adding a lists file if desired.

    opened by friendlyanon 7
  • compiler errors with gcc-7 and clang-4

    compiler errors with gcc-7 and clang-4

    Tried to build the "Motivating Example"s.

    C++14 example was okay with gcc-6. C++14 example and C++17 example did not compile with gcc-7 and clang-4.

    Note: gcc (Ubuntu 7-20170407-0ubuntu2) 7.0.1 20170407 (experimental) [trunk revision 246759] clang version 4.0.0-1ubuntu1 (tags/RELEASE_400/rc1)

    C++14 example compiler errors (gcc 7):

    gcc.compile.c++ bin/gcc-7/release/source/test_magic.o
    In file included from /home/mike/workspace/magic_get/include/boost/pfr/detail/core17.hpp:11:0,
                     from /home/mike/workspace/magic_get/include/boost/pfr/precise/core.hpp:20,
                     from /home/mike/workspace/magic_get/include/boost/pfr/precise.hpp:12,
                     from /home/mike/workspace/magic_get/include/boost/pfr.hpp:12,
                     from source/test_magic.cpp:9:
    /home/mike/workspace/magic_get/include/boost/pfr/detail/core17_generated.hpp: In instantiation of ‘constexpr auto boost::pfr::detail::as_tuple_impl(T&&, boost::pfr::detail::size_t_<3>) [with T = const my_struct&; boost::pfr::detail::size_t_<3> = std::integral_constant<long unsigned int, 3>]’:
    /home/mike/workspace/magic_get/include/boost/pfr/detail/core17_generated.hpp:1032:43:   required from ‘constexpr auto boost::pfr::detail::as_tuple(const T&) [with T = my_struct]’
    /home/mike/workspace/magic_get/include/boost/pfr/precise/io.hpp:45:69:   required from ‘void boost::pfr::write(std::basic_ostream<_CharT, _Traits>&, const T&) [with Char = char; Traits = std::char_traits<char>; T = my_struct]’
    /home/mike/workspace/magic_get/include/boost/pfr/precise/ops.hpp:129:26:   required from ‘boost::pfr::detail::enable_not_ostreamable_t<std::basic_ostream<_CharT, _Traits>, T> boost::pfr::ops::operator<<(std::basic_ostream<_CharT, _Traits>&, const T&) [with Char = char; Traits = std::char_traits<char>; T = my_struct; boost::pfr::detail::enable_not_ostreamable_t<std::basic_ostream<_CharT, _Traits>, T> = std::basic_ostream<char>&]’
    source/test_magic.cpp:22:27:   required from here
    /home/mike/workspace/magic_get/include/boost/pfr/detail/core17_generated.hpp:57:9: error: ‘std::tuple_size<const my_struct>::value’ is not an integral constant expression
       auto& [a,b,c] = std::forward<T>(val);
             ^~~~~~~
    In file included from /home/mike/workspace/magic_get/include/boost/pfr/precise/ops.hpp:15:0,
                     from /home/mike/workspace/magic_get/include/boost/pfr/precise.hpp:14,
                     from /home/mike/workspace/magic_get/include/boost/pfr.hpp:12,
                     from source/test_magic.cpp:9:
    /home/mike/workspace/magic_get/include/boost/pfr/precise/io.hpp: In instantiation of ‘void boost::pfr::write(std::basic_ostream<_CharT, _Traits>&, const T&) [with Char = char; Traits = std::char_traits<char>; T = my_struct]’:
    /home/mike/workspace/magic_get/include/boost/pfr/precise/ops.hpp:129:26:   required from ‘boost::pfr::detail::enable_not_ostreamable_t<std::basic_ostream<_CharT, _Traits>, T> boost::pfr::ops::operator<<(std::basic_ostream<_CharT, _Traits>&, const T&) [with Char = char; Traits = std::char_traits<char>; T = my_struct; boost::pfr::detail::enable_not_ostreamable_t<std::basic_ostream<_CharT, _Traits>, T> = std::basic_ostream<char>&]’
    source/test_magic.cpp:22:27:   required from here
    /home/mike/workspace/magic_get/include/boost/pfr/precise/io.hpp:45:47: error: invalid use of void expression
         detail::print_impl<0, fields_count>::print(out, detail::as_tuple(value));
         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
        "g++"  -ftemplate-depth-128 -march=native -ftemplate-depth=256 -std=c++17 -O3 -finline-functions -Wno-inline -Wall -fPIC  -DBOOST_ALL_DYN_LINK -DNDEBUG  -I"/home/mike/workspace/magic_get/include" -I"include" -c -o "bin/gcc-7/release/source/test_magic.o" "source/test_magic.cpp"
    
    ...failed gcc.compile.c++ bin/gcc-7/release/source/test_magic.o...
    

    C++17 example compiler errors (gcc-7):

    gcc.compile.c++ bin/gcc-7/release/source/test_magic.o
    In file included from /home/mike/workspace/magic_get/include/boost/pfr/detail/core17.hpp:11:0,
                     from /home/mike/workspace/magic_get/include/boost/pfr/precise/core.hpp:20,
                     from /home/mike/workspace/magic_get/include/boost/pfr/precise.hpp:12,
                     from /home/mike/workspace/magic_get/include/boost/pfr.hpp:12,
                     from source/test_magic.cpp:9:
    /home/mike/workspace/magic_get/include/boost/pfr/detail/core17_generated.hpp: In instantiation of ‘constexpr auto boost::pfr::detail::as_tuple_impl(T&&, boost::pfr::detail::size_t_<2>) [with T = const my_struct&; boost::pfr::detail::size_t_<2> = std::integral_constant<long unsigned int, 2>]’:
    /home/mike/workspace/magic_get/include/boost/pfr/detail/core17_generated.hpp:1032:43:   required from ‘constexpr auto boost::pfr::detail::as_tuple(const T&) [with T = my_struct]’
    /home/mike/workspace/magic_get/include/boost/pfr/precise/io.hpp:45:69:   required from ‘void boost::pfr::write(std::basic_ostream<_CharT, _Traits>&, const T&) [with Char = char; Traits = std::char_traits<char>; T = my_struct]’
    /home/mike/workspace/magic_get/include/boost/pfr/precise/ops.hpp:129:26:   required from ‘boost::pfr::detail::enable_not_ostreamable_t<std::basic_ostream<_CharT, _Traits>, T> boost::pfr::ops::operator<<(std::basic_ostream<_CharT, _Traits>&, const T&) [with Char = char; Traits = std::char_traits<char>; T = my_struct; boost::pfr::detail::enable_not_ostreamable_t<std::basic_ostream<_CharT, _Traits>, T> = std::basic_ostream<char>&]’
    source/test_magic.cpp:21:27:   required from here
    /home/mike/workspace/magic_get/include/boost/pfr/detail/core17_generated.hpp:51:9: error: ‘std::tuple_size<const my_struct>::value’ is not an integral constant expression
       auto& [a,b] = std::forward<T>(val);
             ^~~~~
    In file included from /home/mike/workspace/magic_get/include/boost/pfr/precise/ops.hpp:15:0,
                     from /home/mike/workspace/magic_get/include/boost/pfr/precise.hpp:14,
                     from /home/mike/workspace/magic_get/include/boost/pfr.hpp:12,
                     from source/test_magic.cpp:9:
    /home/mike/workspace/magic_get/include/boost/pfr/precise/io.hpp: In instantiation of ‘void boost::pfr::write(std::basic_ostream<_CharT, _Traits>&, const T&) [with Char = char; Traits = std::char_traits<char>; T = my_struct]’:
    /home/mike/workspace/magic_get/include/boost/pfr/precise/ops.hpp:129:26:   required from ‘boost::pfr::detail::enable_not_ostreamable_t<std::basic_ostream<_CharT, _Traits>, T> boost::pfr::ops::operator<<(std::basic_ostream<_CharT, _Traits>&, const T&) [with Char = char; Traits = std::char_traits<char>; T = my_struct; boost::pfr::detail::enable_not_ostreamable_t<std::basic_ostream<_CharT, _Traits>, T> = std::basic_ostream<char>&]’
    source/test_magic.cpp:21:27:   required from here
    /home/mike/workspace/magic_get/include/boost/pfr/precise/io.hpp:45:47: error: invalid use of void expression
         detail::print_impl<0, fields_count>::print(out, detail::as_tuple(value));
         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
        "g++"  -ftemplate-depth-128 -march=native -ftemplate-depth=256 -std=c++17 -O3 -finline-functions -Wno-inline -Wall -fPIC  -DBOOST_ALL_DYN_LINK -DNDEBUG  -I"/home/mike/workspace/magic_get/include" -I"include" -c -o "bin/gcc-7/release/source/test_magic.o" "source/test_magic.cpp"
    
    ...failed gcc.compile.c++ bin/gcc-7/release/source/test_magic.o...
    

    C++17 example compiler errors (clang-4):

    clang-linux.compile.c++.without-pth bin/clang-linux-4.0.0/release/source/test_magic.o
    In file included from source/test_magic.cpp:9:
    In file included from /home/mike/workspace/magic_get/include/boost/pfr.hpp:12:
    In file included from /home/mike/workspace/magic_get/include/boost/pfr/precise.hpp:12:
    In file included from /home/mike/workspace/magic_get/include/boost/pfr/precise/core.hpp:20:
    In file included from /home/mike/workspace/magic_get/include/boost/pfr/detail/core17.hpp:11:
    /home/mike/workspace/magic_get/include/boost/pfr/detail/core17_generated.hpp:51:9: error: cannot decompose this type; 'std::tuple_size<const my_struct>::value' is not a valid integral constant expression
      auto& [a,b] = std::forward<T>(val);
            ^
    /home/mike/workspace/magic_get/include/boost/pfr/detail/core17_generated.hpp:1032:30: note: in instantiation of function template specialization 'boost::pfr::detail::as_tuple_impl<const my_struct &>' requested here
      return boost::pfr::detail::as_tuple_impl(val, fields_count_tag{});
                                 ^
    /home/mike/workspace/magic_get/include/boost/pfr/precise/io.hpp:45:61: note: in instantiation of function template specialization 'boost::pfr::detail::as_tuple<my_struct>' requested here
        detail::print_impl<0, fields_count>::print(out, detail::as_tuple(value));
                                                                ^
    /home/mike/workspace/magic_get/include/boost/pfr/precise/ops.hpp:129:21: note: in instantiation of function template specialization 'boost::pfr::write<char, std::char_traits<char>, my_struct>' requested here
            boost::pfr::write(out, value);
                        ^
    source/test_magic.cpp:21:24: note: in instantiation of function template specialization 'boost::pfr::ops::operator<<<char, std::char_traits<char>, my_struct>' requested here
            << " fields: " << s << "\n";
                           ^
    4 errors generated.
    
      "clang++" -c -x c++ -march=native -std=c++1z -O3 -Wno-inline -Wall -fPIC  -DBOOST_ALL_DYN_LINK -DNDEBUG -I"/home/mike/workspace/magic_get/include" -I"include" -o "bin/clang-linux-4.0.0/release/source/test_magic.o" "source/test_magic.cpp"
    
    ...failed clang-linux.compile.c++.without-pth bin/clang-linux-4.0.0/release/source/test_magic.o...
    
    bug 
    opened by octopus-prime 7
  • Reopen #27

    Reopen #27

    Issue #27 should have been fixed in latest master but it doesn't.

    Compiling

    #include <memory>
    #include <boost/pfr.hpp>
    
    struct Message {
      std::unique_ptr<int> data;
    };
    
    int main(int argc, char* argv[]) {
      Message message;
      auto& ptr = boost::pfr::get<0>(message);
      return 0;
    }
    

    gives me

    In file included from /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/boost/pfr/detail/core14.hpp:13:0,
                     from /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/boost/pfr/precise/core.hpp:23,
                     from /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/boost/pfr/precise.hpp:12,
                     from /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/boost/pfr.hpp:12,
                     from /tmp/untitled/main.cpp:2:
    /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/boost/pfr/detail/core14_loophole.hpp: In instantiation of ‘struct boost::pfr::detail::loophole_type_list<Message, std::integer_sequence<unsigned int, 0u> >’:
    /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/boost/pfr/detail/core14_loophole.hpp:108:72:   required from ‘auto boost::pfr::detail::tie_as_tuple_loophole_impl(T&) [with T = Message]’
    /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/boost/pfr/detail/core14_loophole.hpp:199:58:   required from ‘auto boost::pfr::detail::tie_as_tuple(T&) [with T = Message]’
    /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/boost/pfr/precise/core.hpp:50:64:   required from ‘constexpr decltype(auto) boost::pfr::get(T&) [with unsigned int I = 0u; T = Message]’
    /tmp/untitled/main.cpp:10:41:   required from here
    /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/boost/pfr/detail/core14_loophole.hpp:98:68: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp = std::default_delete<int>]’
         : sequence_tuple::tuple< decltype(T{ loophole_ubiq<T, I>{}... }, 0) >
                                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~
    In file included from /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/c++/6.3.0/memory:81:0,
                     from /tmp/untitled/main.cpp:1:
    /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/c++/6.3.0/bits/unique_ptr.h:359:7: note: declared here
           unique_ptr(const unique_ptr&) = delete;
           ^~~~~~~~~~
    In file included from /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/boost/pfr/detail/core14.hpp:13:0,
                     from /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/boost/pfr/precise/core.hpp:23,
                     from /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/boost/pfr/precise.hpp:12,
                     from /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/boost/pfr.hpp:12,
                     from /tmp/untitled/main.cpp:2:
    /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/boost/pfr/detail/core14_loophole.hpp:87:15: note:   after user-defined conversion: constexpr boost::pfr::detail::loophole_ubiq<T, N>::operator U&() const [with U = std::unique_ptr<int>; unsigned int <anonymous> = 1u; T = Message; unsigned int N = 0u]
         constexpr operator U&() const noexcept; // `const` here helps to avoid ambiguity in loophole instantiations. optional_like test validate that behavior.
                   ^~~~~~~~
    /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/boost/pfr/detail/core14_loophole.hpp:100:58: error: use of ‘auto boost::pfr::detail::loophole(boost::pfr::detail::tag<Message, 0u>)’ before deduction of ‘auto’
         using type = sequence_tuple::tuple< decltype(loophole(tag<T, I>{}))... >;
                                                      ~~~~~~~~^~~~~~~~~~~~~
    /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/boost/pfr/detail/core14_loophole.hpp:100:58: error: use of ‘auto boost::pfr::detail::loophole(boost::pfr::detail::tag<Message, 0u>)’ before deduction of ‘auto’
    In file included from /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/boost/pfr/precise.hpp:12:0,
                     from /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/boost/pfr.hpp:12,
                     from /tmp/untitled/main.cpp:2:
    /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/boost/pfr/precise/core.hpp: In instantiation of ‘constexpr decltype(auto) boost::pfr::get(T&) [with unsigned int I = 0u; T = Message]’:
    /tmp/untitled/main.cpp:10:41:   required from here
    /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/boost/pfr/precise/core.hpp:50:42: error: invalid use of void expression
         return detail::sequence_tuple::get<I>( detail::tie_as_tuple(val) );
                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    /tmp/untitled/main.cpp: In function ‘int main(int, char**)’:
    /tmp/untitled/main.cpp:10:41: error: forming reference to void
       auto& ptr = boost::pfr::get<0>(message);
                                             ^
    make[2]: *** [CMakeFiles/untitled.dir/main.cpp.o] Error 1
    make[1]: *** [CMakeFiles/untitled.dir/all] Error 2
    
    opened by filcuc 6
  • Is there some way to get the fields by name?

    Is there some way to get the fields by name?

    magic_get is really magic, however magic_get can only get fileds by index, sometimes i need get fields by name, is there some way to get the fields by name?

    enhancement help wanted wontfix 
    opened by qicosmos 6
  • Support std::optional<>

    Support std::optional<>

    It seems that std::experimental::optional (c++14) or std::optional(c++17) are not supported

    n file included from /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/boost/pfr/detail/core14_loophole.hpp:29:0,
                     from /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/boost/pfr/detail/core14.hpp:13,
                     from /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/boost/pfr/precise/core.hpp:24,
                     from /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/boost/pfr/precise.hpp:12,
                     from /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/boost/pfr.hpp:12,
                     from /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/LibVimarIPCParser/BaseValueHandlers.h:6,
                     from /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/LibVimarIPCParser/StdValueHandlers.h:4,
                     from /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/LibVimarIPCParser/UserParser.h:4,
                     from /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/LibVimarIPCParser/SystemFunctionParser.h:10,
                     from /home/cucchetf/workspace/p378_ipconnectorserver/src/ipc/SFClientIPC.h:5,
                     from /home/cucchetf/workspace/p378_ipconnectorserver/src/ipc/SFClientIPC.cpp:1:
    /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/boost/pfr/detail/offset_based_getter.hpp: In instantiation of ‘class boost::pfr::detail::offset_based_getter<ipconnector::Temp, boost::pfr::detail::sequence_tuple::tuple<int, int> >’:
    /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/boost/pfr/detail/core14_loophole.hpp:154:61:   required from ‘auto boost::pfr::detail::tie_as_tuple_loophole_impl(T&) [with T = ipconnector::Temp]’
    /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/boost/pfr/detail/core14_loophole.hpp:255:55:   required from ‘void boost::pfr::detail::for_each_field_dispatcher(T&, F&&, std::index_sequence<I ...>) [with T = ipconnector::Temp; F = boost::pfr::for_each_field(T&&, F&&) [with T = ipconnector::Temp&; F = ipconnector::SFClientIPC::ModifyScene(const VimarIPCParser::SystemFunctionParser::ModifySceneRequest&)::<lambda(const auto:9&)>]::<lambda(auto:1&&)>; unsigned int ...I = {0u, 1u}; std::index_sequence<I ...> = std::integer_sequence<unsigned int, 0u, 1u>]’
    /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/boost/pfr/precise/core.hpp:140:52:   required from ‘void boost::pfr::for_each_field(T&&, F&&) [with T = ipconnector::Temp&; F = ipconnector::SFClientIPC::ModifyScene(const VimarIPCParser::SystemFunctionParser::ModifySceneRequest&)::<lambda(const auto:9&)>]’
    /home/cucchetf/workspace/p378_ipconnectorserver/src/ipc/SFClientIPC.cpp:117:56:   required from here
    /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/boost/pfr/detail/offset_based_getter.hpp:63:3: error: static assertion failed: ====================> Boost.PFR: Member sequence does not indicate correct size for struct type!
       static_assert(sizeof(U) == sizeof(S), "====================> Boost.PFR: Member sequence does not indicate correct size for struct type!");
       ^~~~~~~~~~~~~
    In file included from /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/boost/pfr/detail/core14.hpp:13:0,
                     from /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/boost/pfr/precise/core.hpp:24,
                     from /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/boost/pfr/precise.hpp:12,
                     from /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/boost/pfr.hpp:12,
                     from /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/LibVimarIPCParser/BaseValueHandlers.h:6,
                     from /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/LibVimarIPCParser/StdValueHandlers.h:4,
                     from /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/LibVimarIPCParser/UserParser.h:4,
                     from /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/LibVimarIPCParser/SystemFunctionParser.h:10,
                     from /home/cucchetf/workspace/p378_ipconnectorserver/src/ipc/SFClientIPC.h:5,
                     from /home/cucchetf/workspace/p378_ipconnectorserver/src/ipc/SFClientIPC.cpp:1:
    /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/boost/pfr/detail/core14_loophole.hpp: In instantiation of ‘void boost::pfr::detail::for_each_field_dispatcher(T&, F&&, std::index_sequence<I ...>) [with T = ipconnector::Temp; F = boost::pfr::for_each_field(T&&, F&&) [with T = ipconnector::Temp&; F = ipconnector::SFClientIPC::ModifyScene(const VimarIPCParser::SystemFunctionParser::ModifySceneRequest&)::<lambda(const auto:9&)>]::<lambda(auto:1&&)>; unsigned int ...I = {0u, 1u}; std::index_sequence<I ...> = std::integer_sequence<unsigned int, 0u, 1u>]’:
    /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/boost/pfr/precise/core.hpp:140:52:   required from ‘void boost::pfr::for_each_field(T&&, F&&) [with T = ipconnector::Temp&; F = ipconnector::SFClientIPC::ModifyScene(const VimarIPCParser::SystemFunctionParser::ModifySceneRequest&)::<lambda(const auto:9&)>]’
    /home/cucchetf/workspace/p378_ipconnectorserver/src/ipc/SFClientIPC.cpp:117:56:   required from here
    /opt/vrag/releases/private/cucchetf-vimar-agx-dbg-latest/sdk/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/boost/pfr/detail/core14_loophole.hpp:254:23: error: use of ‘boost::pfr::for_each_field(T&&, F&&)::<lambda(auto:1&&)> mutable [with auto:1 = boost::pfr::detail::sequence_tuple::tuple<int&, int&>; T = ipconnector::Temp&; F = ipconnector::SFClientIPC::ModifyScene(const VimarIPCParser::SystemFunctionParser::ModifySceneRequest&)::<lambda(const auto:9&)>]’ before deduction of ‘auto’
         std::forward<F>(f)(
         ~~~~~~~~~~~~~~~~~~^
             boost::pfr::detail::tie_as_tuple_loophole_impl(t)
             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         );
         ~                  
    
    wontfix 
    opened by filcuc 5
  • vs2019 bulid error ..

    vs2019 bulid error ..

    Visual Studio 2019 (v142) error C2338: ====================> Boost.PFR: Types with user specified constructors (non-aggregate initializable types) are not supported. 查看对正在编译的函数 模板 实例化“size_t boost::pfr::detail::fields_count(void) noexcept”的引用

    struct msg_HelperStr { HelperStrType _HelperType; std::string _HelperStr; };

    bug 
    opened by bilbilemm 4
  • Interop With BOOST.FUSION

    Interop With BOOST.FUSION

    Is it possible to support interoperation with boost fusion library i.e. make simple aggregates a boost fusion sequence? It allows to drop fusion macros like BOOST_FUSION_ADAPT_STRUCT().

    opened by sergegers 0
  • Can packed structures be supported?

    Can packed structures be supported?

    I noticed that packed structures are not supported, while it is not mentioned in documentation.

    For example:

    struct __attribute__ ((packed)) A
    {
        int x;
        int z;
        bool y;
    };
    

    The error message is following:

    static_assert(sizeof(U) == sizeof(S), "====================> Boost.PFR: Member sequence does not indicate correct size for struct type! Maybe the user-provided type is not a SimpleAggregate?");
                  ~~~~~~~~~~^~~~~~~~~~~~
    

    Link: https://godbolt.org/z/Exo16Mods

    However, the class should be an Aggregate, as

    An aggregate is an array or a class (clause 9) with no user-declared constructors (12.1), no private or protected non-static data members (clause 11), no base classes (clause 10), and no virtual functions (10.3).

    Is there a technical obstacle on adding packed structures?

    opened by pavelkryukov 4
  • warning: Undefined or garbage value returned to caller [clang-analyzer-core.uninitialized.UndefReturn]

    warning: Undefined or garbage value returned to caller [clang-analyzer-core.uninitialized.UndefReturn]

    Clang-tidy 12 is complaining:

    /home/runner/work/cherry_blazer/cherry_blazer/_deps/boost_pfr-src/include/boost/pfr/detail/sequence_tuple.hpp:53:5: warning: Undefined or garbage value returned to caller [clang-analyzer-core.uninitialized.UndefReturn]
        return t.value;
        ^
    /home/runner/work/cherry_blazer/cherry_blazer/src/canvas.cc:126:37: note: Assuming 'nth_batch' is < 'batch_count'
        for (std::size_t nth_batch = 0; nth_batch < batch_count; ++nth_batch) {
                                        ^
    /home/runner/work/cherry_blazer/cherry_blazer/src/canvas.cc:126:5: note: Loop condition is true.  Entering loop body
        for (std::size_t nth_batch = 0; nth_batch < batch_count; ++nth_batch) {
        ^
    /home/runner/work/cherry_blazer/cherry_blazer/src/canvas.cc:127:9: note: Loop condition is true.  Entering loop body
            for (std::size_t nth_color = 0; nth_color < batch_size; ++nth_color) {
            ^
    /home/runner/work/cherry_blazer/cherry_blazer/src/canvas.cc:128:13: note: Calling 'for_each_field<cherry_blazer::Color &, (lambda at /home/runner/work/cherry_blazer/cherry_blazer/src/canvas.cc:129:62)>'
                boost::pfr::for_each_field(
                ^
    /home/runner/work/cherry_blazer/cherry_blazer/_deps/boost_pfr-src/include/boost/pfr/core.hpp:187:5: note: Calling 'for_each_field_dispatcher<cherry_blazer::Color, (lambda at /home/runner/work/cherry_blazer/cherry_blazer/_deps/boost_pfr-src/include/boost/pfr/core.hpp:189:9), 0, 1, 2>'
        ::boost::pfr::detail::for_each_field_dispatcher(
        ^
    /home/runner/work/cherry_blazer/cherry_blazer/_deps/boost_pfr-src/include/boost/pfr/detail/core17.hpp:64:5: note: Calling 'operator()'
        std::forward<F>(f)(
        ^
    /home/runner/work/cherry_blazer/cherry_blazer/_deps/boost_pfr-src/include/boost/pfr/core.hpp:194:13: note: Calling 'for_each_field_impl<boost::pfr::detail::sequence_tuple::tuple<double &, double &, double &>, (lambda at /home/runner/work/cherry_blazer/cherry_blazer/src/canvas.cc:129:62), 0, 1, 2>'
                ::boost::pfr::detail::for_each_field_impl(
                ^
    /home/runner/work/cherry_blazer/cherry_blazer/_deps/boost_pfr-src/include/boost/pfr/detail/for_each_field_impl.hpp:35:44: note: Calling 'get<0, double &, double &, double &>'
             detail::for_each_field_impl_apply(sequence_tuple::get<I>(t), std::forward<F>(f), size_t_<I>{}, 1L),
                                               ^
    /home/runner/work/cherry_blazer/cherry_blazer/_deps/boost_pfr-src/include/boost/pfr/detail/sequence_tuple.hpp:92:12: note: Calling 'get_impl<0, double &>'
        return sequence_tuple::get_impl<N>(t);
               ^
    /home/runner/work/cherry_blazer/cherry_blazer/_deps/boost_pfr-src/include/boost/pfr/detail/sequence_tuple.hpp:53:5: note: Undefined or garbage value returned to caller
        return t.value;
        ^
    

    Not sure if this is something easily reproducible or not, I haven't tried. Just my first time using this library.

    opened by hgkjshegfskef 2
  • is it a way to serialize field names?

    is it a way to serialize field names?

    #ifdef _STR
    #  error _STR already defined
    #endif
    #define _STR(S) BOOST_METAPARSE_STRING(S){}
    
    struct gps_position
    {
        field<int, (name=_STR("degrees"))> degrees;
        field<int, (name=_STR("minutes"))> minutes;
        field<float, (name=_STR("seconds"))> seconds;
    };
    

    We need to:

    1. field<T, A> template class, this class is just a wrapper to T with std::reference_wrapper-like(??) iface.
    2. name object with overloaded operator=(std::string_view), and this overloaded operator must be constexpr

    This short example: https://godbolt.org/z/nT4bdrnKc Interface of field_t<T,A> class is not ideal, but this short example shows that structure with named fields are possible.

    opened by denzor200 3
  • `BOOST_PFR_FUNCTIONS_FOR` doesn't nest

    `BOOST_PFR_FUNCTIONS_FOR` doesn't nest

    I don't know if this is a bug or feature, but BOOST_PFR_FUNCTIONS_FOR requires structure members to have an std::hash specialization, but it doesn't itself provide one, so the following example fails to compile:

    #include <boost/pfr/functions_for.hpp>
    
    struct A { int a; };
    BOOST_PFR_FUNCTIONS_FOR(A);
    // namespace std { template<> struct hash<A> { size_t operator()(A); }; }
    
    struct B { A a; };
    BOOST_PFR_FUNCTIONS_FOR(B);
    

    Godbolt

    Uncommenting the hash specialization will make this code compile, but it's bothersome to do this for every type that just needs some comparison and print operations. Would it be possible to have a BOOST_PFR_FUNCTIONS_FOR version that doesn't try to generate a hash function? (Especially that it generates a hash_value function that is only compatible with boost containers, not an std::hash specialization that is a more compatible solution with C++11 or later.) Or at least make hash_fields compatible with hash_value?

    opened by u3shit 0
Releases(2.0.3)
  • 2.0.3(Oct 2, 2021)

    • Added missing #include <memory> for inclusion of std::addressof
    • Fixed -Wzero-length-array warning when dealing with empty aggregates
    • Fixed compilation on msvc compilers <= 1920 (thanks to Alexey Romanov aka @alexey-romanov)
    • Added basic CMakeLists.txt support (thanks to @pdimov aka Peter Dimov)
    • Multiple improvements for docs, including links to https://github.com/apolukhin/pfr_non_boost
    • Added misc/strip_boost_namespace.sh script to remove boost:: and BOOST_ prefixes
    Source code(tar.gz)
    Source code(zip)
  • 2.0.2(May 19, 2021)

    • A MurMur Hash based implementation of hash_combine() is now used to reduce collisions count and improve quality of boost::pfr::hash_value()
    • Visual Studio 2017 now supported in C++14 mode (thanks to Denis Mikhailov aka @denzor200)
    • Issues found by inspect tool were fixed
    • Fixed some warnings, including removal of extra semicolons in include/boost/pfr/detail/fields_count.hpp (fixes #72)
    • Added a compile time assert for inherited types (thanks to Denis Mikhailov aka @denzor200)
    • Reflection of aggregates with non movable fields is now possible if guaranteed copy elision is on
    • Fixed spelling issues
    Source code(tar.gz)
    Source code(zip)
  • 2.0.1(Dec 18, 2020)

    • Comparison functions are now constexpr
    • Aggregates with members that have lost const qualifiers on SFINAE in constructor (like std::optional<std::chrono::duration<A,B>> from libc++) now could be reflected again
    • Multiple typos fixed
    Source code(tar.gz)
    Source code(zip)
  • 2.0.0(Nov 27, 2020)

    First Boost release of the library. Significant changes since version 1.0.x:

    • Removed the Flat reflection
    • Removed global_ops.hpp
    • boost::pfr::ops::operator* were changed to functions and moved to boost::pfr:: namespace
    • Big rewrite of docs
    • Better testing and improved diagnostics
    • Helper script now works with Python2 and Python3
    Source code(tar.gz)
    Source code(zip)
  • 1.0.4(Aug 20, 2020)

  • 1.0.3(Aug 16, 2020)

  • 1.0.2(Aug 14, 2020)

  • 1.0.1(Jul 7, 2020)

Owner
Boost.org
Boost provides free peer-reviewed portable C++ source libraries.
Boost.org
Gesture-Detecting-Macro-Keyboard - Glorified Bluetooth macro keyboard with machine learning (TensorFlow Lite for Microcontrollers) running on an ESP32.

Gesture detection tldr; Glorified Bluetooth macro keyboard with machine learning (TensorFlow Lite for Microcontrollers) running on an ESP32. Main feat

Jakob Krantz 59 Apr 4, 2022
WTD is a python tool for replacing values with the C preprocessor macro which defined them.

Where's That Define WTD is a python tool for replacing values with the C preprocessor macro which defined them. An example of this is when trying to u

Caleb Connolly 5 Mar 28, 2022
Tuple but with tags.

tagged_tuple Tuple but with tags. Example code: #include <iostream> #include "tagged_tuple.hpp" int main() { // defines binding between types (na

null 2 Nov 17, 2021
Arbitrary Precision provides C++ long integer types that behave as basic integer types. This library aims to be intuitive and versatile in usage, rather than fast.

Arbitrary Precision (AP) Cross-platform and cross-standard header-only arbitrary precision arithmetic library. Currently it offers integer types that

null 14 Apr 22, 2022
Invoke.hpp - std::invoke/std::apply analogs for C++11/14

invoke.hpp std::invoke/std::apply analogs for C++11/14 Requirements gcc >= 4.9 clang >= 3.8 msvc >= 2015 Installation invoke.hpp is a header-only libr

Matvey Cherevko 32 Apr 27, 2022
Loads a signed kernel driver which allows you to map any driver to kernel mode without any traces of the signed / mapped driver.

CosMapper Loads a signed kernel driver (signed with leaked cert) which allows you to map any driver to kernel mode without any traces of the signed /

null 94 May 4, 2022
Automatically load dlls into any executables without replacing any files!

Automatically loaded dll using xinput9_1_0 proxy. Please put the modified xinput9_1_0.dll in the executable's directory.

null 11 Apr 17, 2022
A C++14 macro to get the type of the current class without naming it

self_macro C++14 header only library that exposes a macro that creates a type alias for the current class without naming it. Also exposes macros that

Mital Ashok 8 Jan 14, 2022
Cobalt Strike User-Defined Reflective Loader written in Assembly & C for advanced evasion capabilities.

Cobalt Strike User-Defined Reflective Loader Cobalt Strike User-Defined Reflective Loader written in Assembly & C for advanced evasion capabilities. B

Bobby Cooke 649 May 7, 2022
Samir Teymurov 1 Oct 6, 2021
My_Shell is a user-defined interactive shell written in C that works similar to the original shell in linux

MY_SHELL Overview My_Shell is a user-defined interactive shell written in C that works similar to the original shell and it can execeute many of the l

Greeshma 1 Nov 22, 2021
BokuLoader - Cobalt Strike User-Defined Reflective Loader written in Assembly & C for advanced evasion capabilities.

BokuLoader - Cobalt Strike Reflective Loader Cobalt Strike User-Defined Reflective Loader written in Assembly & C for advanced evasion capabilities. B

Bobby Cooke 650 May 12, 2022
ToPS is an objected-oriented framework implemented using C++ that facilitates the integration of probabilistic models for sequences over a user defined alphabet

ToPS is an objected-oriented framework implemented using C++ that facilitates the integration of probabilistic models for sequences over a user defined alphabet

Andre Yoshiaki Kashiwabara 35 Mar 6, 2022
A light-weight Flutter Engine Embedder based on HADK ,which for Android devices that runs without any java code

flutter-hadk A light-weight Flutter Engine Embedder based on HADK ,which for Android devices that runs without any java code 1.Build by android-ndk-to

null 13 Nov 8, 2021
32blit SDK boilerplate for the PicoSystem RP2040-based handheld

PicoSystem 32blit Boilerplate This is a basic template for starting 32blit projects for the Pimoroni PicoSystem. It shows a minimal code layout and as

32blit 10 Mar 23, 2022
ESP32 + GitHub Actions + Husarnet. A boilerplate project for ESP32 allowing in-field firmware update using GitHub Actions workflow.

esp32-internet-ota ESP32 + GitHub Actions + Husarnet. A boilerplate project for ESP32 allowing in-field firmware update using GitHub Actions workflow.

Husarnet 28 Apr 30, 2022
Boilerplate-free YAML parsing for C++

AutoYAML AutoYAML is a Clang/LLVM/LibTooling-based program that automatically generates yaml-cpp conversion code for C++ record types. Usage As a moti

Timo Nicolai 10 Nov 12, 2021
Boilerplate to create a project with: STM32 + Ethernet + micro-ROS + FreeRTOS + Arduino + PlatformIO

micro_ros_stm32_template Boilerplate to create a project with: STM32 + Ethernet + micro-ROS + FreeRTOS + Arduino + PlatformIO Default config STM32F407

Husarion 11 May 7, 2022
Poc to test my little friend features without any sdk

poc.vic-hack POC to test my little friend "vector" features without any sdk Ultimate goal - being able to write own firmware components without propri

Oleg Lytvynenko 8 Feb 26, 2022