Add descriptor_by_name

This commit is contained in:
Peter Dimov
2021-10-27 04:13:29 +03:00
parent 2935bca3b1
commit 448174f346
4 changed files with 119 additions and 0 deletions

View File

@@ -14,5 +14,6 @@
#include <boost/describe/enum_to_string.hpp>
#include <boost/describe/enum_from_string.hpp>
#include <boost/describe/operators.hpp>
#include <boost/describe/descriptor_by_name.hpp>
#endif // #ifndef BOOST_DESCRIBE_HPP_INCLUDED

View File

@@ -0,0 +1,52 @@
#ifndef BOOST_DESCRIBE_DESCRIPTOR_BY_NAME_HPP_INCLUDED
#define BOOST_DESCRIBE_DESCRIPTOR_BY_NAME_HPP_INCLUDED
// Copyright 2021 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/describe/detail/config.hpp>
#if defined(BOOST_DESCRIBE_CXX14)
#include <boost/mp11/algorithm.hpp>
#include <boost/mp11/bind.hpp>
#include <boost/mp11/integral.hpp>
namespace boost
{
namespace describe
{
namespace detail
{
// cx_streq already defined in members.hpp
constexpr bool dbn_cx_streq( char const * s1, char const * s2 )
{
for( ;; )
{
if( *s1 != *s2 ) return false;
if( *s1 == 0 ) return true;
++s1;
++s2;
}
}
template<class D, class N> using match_by_name = mp11::mp_bool<dbn_cx_streq(D::name, N::name())>;
#define BOOST_DESCRIBE_MAKE_NAME_IMPL2(s, k) struct _boost_name_##s##_##k { static constexpr char const * name() { return #s; } }
#define BOOST_DESCRIBE_MAKE_NAME_IMPL(s, k) BOOST_DESCRIBE_MAKE_NAME_IMPL2(s, k)
} // namespace detail
#define BOOST_DESCRIBE_MAKE_NAME(s) BOOST_DESCRIBE_MAKE_NAME_IMPL(s, __LINE__)
template<class L, class N> using descriptor_by_name = mp11::mp_at<L, mp11::mp_find_if_q<L, mp11::mp_bind_back<detail::match_by_name, N>>>;
} // namespace describe
} // namespace boost
#endif // defined(BOOST_DESCRIBE_CXX14)
#endif // #ifndef BOOST_DESCRIBE_DESCRIPTOR_BY_NAME_HPP_INCLUDED

View File

@@ -60,6 +60,8 @@ run enum_from_string_test.cpp ;
run operator_eq_test.cpp ;
run operator_lt_test.cpp ;
run descriptor_by_name_test.cpp ;
# examples
obj describe_cxx14 : describe_cxx14.cpp ;

View File

@@ -0,0 +1,64 @@
// Copyright 2021 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/describe/descriptor_by_name.hpp>
#include <boost/describe/class.hpp>
#include <boost/describe/members.hpp>
#include <boost/core/lightweight_test.hpp>
#if !defined(BOOST_DESCRIBE_CXX14)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Skipping test because C++14 is not available")
int main() {}
#else
struct X
{
int a = 1;
int b = 2;
};
BOOST_DESCRIBE_STRUCT(X, (), (a, b))
struct Y
{
int a = 1;
int c = 3;
};
BOOST_DESCRIBE_STRUCT(Y, (), (a, c))
int main()
{
{
using L = boost::describe::describe_members<X, boost::describe::mod_any_access>;
using Na = BOOST_DESCRIBE_MAKE_NAME( a );
using Da = boost::describe::descriptor_by_name<L, Na>;
BOOST_TEST_CSTR_EQ( Da::name, "a" );
using Nb = BOOST_DESCRIBE_MAKE_NAME( b );
using Db = boost::describe::descriptor_by_name<L, Nb>;
BOOST_TEST_CSTR_EQ( Db::name, "b" );
}
{
using L = boost::describe::describe_members<Y, boost::describe::mod_any_access>;
using Na = BOOST_DESCRIBE_MAKE_NAME( a );
using Da = boost::describe::descriptor_by_name<L, Na>;
BOOST_TEST_CSTR_EQ( Da::name, "a" );
using Nc = BOOST_DESCRIBE_MAKE_NAME( c );
using Dc = boost::describe::descriptor_by_name<L, Nc>;
BOOST_TEST_CSTR_EQ( Dc::name, "c" );
}
return boost::report_errors();
}
#endif // !defined(BOOST_DESCRIBE_CXX14)