mirror of
https://github.com/boostorg/describe.git
synced 2026-01-23 05:22:18 +00:00
Compare commits
7 Commits
feature/is
...
feature/is
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
811003ea0c | ||
|
|
bd8be41591 | ||
|
|
f9477bc177 | ||
|
|
d98f4d1f40 | ||
|
|
2e3b6a6791 | ||
|
|
fabf5c7115 | ||
|
|
ec7aec2b3d |
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
@@ -148,6 +148,10 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- toolset: msvc-14.0
|
||||
cxxstd: "14"
|
||||
addrmd: 32,64
|
||||
os: windows-2019
|
||||
- toolset: msvc-14.1
|
||||
cxxstd: "14,17,latest"
|
||||
addrmd: 32,64
|
||||
|
||||
@@ -13,7 +13,8 @@ namespace app
|
||||
{
|
||||
template<class T,
|
||||
class Bd = describe_bases<T, mod_any_access>,
|
||||
class Md = describe_members<T, mod_any_access>>
|
||||
class Md = describe_members<T, mod_any_access>,
|
||||
class En = std::enable_if_t<!std::is_union<T>::value> >
|
||||
bool operator==( T const& t1, T const& t2 )
|
||||
{
|
||||
bool r = true;
|
||||
|
||||
@@ -19,7 +19,7 @@ template<class T,
|
||||
class D1 = boost::describe::describe_members<T,
|
||||
boost::describe::mod_public | boost::describe::mod_protected>,
|
||||
class D2 = boost::describe::describe_members<T, boost::describe::mod_private>,
|
||||
class En = std::enable_if_t<boost::mp11::mp_empty<D2>::value> >
|
||||
class En = std::enable_if_t<boost::mp11::mp_empty<D2>::value && !std::is_union<T>::value> >
|
||||
|
||||
T tag_invoke( boost::json::value_to_tag<T> const&, boost::json::value const& v )
|
||||
{
|
||||
|
||||
@@ -15,7 +15,8 @@ namespace app
|
||||
|
||||
template<class T,
|
||||
class Bd = describe_bases<T, mod_any_access>,
|
||||
class Md = describe_members<T, mod_any_access>>
|
||||
class Md = describe_members<T, mod_any_access>,
|
||||
class En = std::enable_if_t<!std::is_union<T>::value> >
|
||||
std::size_t hash_value( T const & t )
|
||||
{
|
||||
std::size_t r = 0;
|
||||
|
||||
@@ -10,7 +10,8 @@ using namespace boost::describe;
|
||||
|
||||
template<class T,
|
||||
class Bd = describe_bases<T, mod_any_access>,
|
||||
class Md = describe_members<T, mod_any_access>>
|
||||
class Md = describe_members<T, mod_any_access>,
|
||||
class En = std::enable_if_t<!std::is_union<T>::value> >
|
||||
std::ostream& operator<<( std::ostream & os, T const & t )
|
||||
{
|
||||
os << "{";
|
||||
|
||||
@@ -24,8 +24,8 @@ template<class Archive, class T,
|
||||
class D3 = boost::describe::describe_members<T,
|
||||
boost::describe::mod_public | boost::describe::mod_protected>,
|
||||
class D4 = boost::describe::describe_members<T, boost::describe::mod_private>,
|
||||
class En = std::enable_if_t<
|
||||
boost::mp11::mp_empty<D2>::value && boost::mp11::mp_empty<D4>::value> >
|
||||
class En = std::enable_if_t< boost::mp11::mp_empty<D2>::value &&
|
||||
boost::mp11::mp_empty<D4>::value && !std::is_union<T>::value> >
|
||||
|
||||
void serialize( Archive & ar, T & t, boost::serialization::version_type )
|
||||
{
|
||||
|
||||
@@ -13,8 +13,10 @@ auto struct_to_tuple_impl( T const& t, L<D...> )
|
||||
return std::make_tuple( t.*D::pointer... );
|
||||
}
|
||||
|
||||
template<class T, class Dm = desc::describe_members<T,
|
||||
desc::mod_public | desc::mod_inherited>>
|
||||
template<class T,
|
||||
class Dm = desc::describe_members<T,
|
||||
desc::mod_public | desc::mod_inherited>,
|
||||
class En = std::enable_if_t<!std::is_union<T>::value> >
|
||||
auto struct_to_tuple( T const& t )
|
||||
{
|
||||
return struct_to_tuple_impl( t, Dm() );
|
||||
|
||||
@@ -16,7 +16,7 @@ template<class T,
|
||||
class D1 = boost::describe::describe_members<T,
|
||||
boost::describe::mod_public | boost::describe::mod_protected>,
|
||||
class D2 = boost::describe::describe_members<T, boost::describe::mod_private>,
|
||||
class En = std::enable_if_t<boost::mp11::mp_empty<D2>::value> >
|
||||
class En = std::enable_if_t<boost::mp11::mp_empty<D2>::value && !std::is_union<T>::value> >
|
||||
|
||||
void tag_invoke( boost::json::value_from_tag const&, boost::json::value& v, T const & t )
|
||||
{
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace describe
|
||||
friend BOOST_DESCRIBE_PRIVATE_MEMBERS(C, BOOST_DESCRIBE_PP_UNPACK Private)
|
||||
|
||||
#define BOOST_DESCRIBE_STRUCT(C, Bases, Members) \
|
||||
static_assert(std::is_class<C>::value, "BOOST_DESCRIBE_STRUCT should only be used with class types"); \
|
||||
static_assert(std::is_class<C>::value || std::is_union<C>::value, "BOOST_DESCRIBE_STRUCT should only be used with class types"); \
|
||||
BOOST_DESCRIBE_BASES(C, BOOST_DESCRIBE_PP_UNPACK Bases) \
|
||||
BOOST_DESCRIBE_PUBLIC_MEMBERS(C, BOOST_DESCRIBE_PP_UNPACK Members) \
|
||||
BOOST_DESCRIBE_PROTECTED_MEMBERS(C) \
|
||||
@@ -60,7 +60,7 @@ namespace describe
|
||||
BOOST_DESCRIBE_MAYBE_UNUSED friend BOOST_DESCRIBE_PRIVATE_MEMBERS_(C BOOST_DESCRIBE_PP_UNPACK Private)
|
||||
|
||||
#define BOOST_DESCRIBE_STRUCT(C, Bases, Members) \
|
||||
static_assert(std::is_class<C>::value, "BOOST_DESCRIBE_STRUCT should only be used with class types"); \
|
||||
static_assert(std::is_class<C>::value || std::is_union<C>::value, "BOOST_DESCRIBE_STRUCT should only be used with class types"); \
|
||||
BOOST_DESCRIBE_MAYBE_UNUSED BOOST_DESCRIBE_BASES_(C BOOST_DESCRIBE_PP_UNPACK Bases) \
|
||||
BOOST_DESCRIBE_MAYBE_UNUSED BOOST_DESCRIBE_PUBLIC_MEMBERS_(C BOOST_DESCRIBE_PP_UNPACK Members) \
|
||||
BOOST_DESCRIBE_MAYBE_UNUSED BOOST_DESCRIBE_PROTECTED_MEMBERS_(C) \
|
||||
|
||||
@@ -109,49 +109,49 @@ namespace operators
|
||||
{
|
||||
|
||||
template<class T> std::enable_if_t<
|
||||
has_describe_bases<T>::value && has_describe_members<T>::value, bool>
|
||||
has_describe_bases<T>::value && has_describe_members<T>::value && !std::is_union<T>::value, bool>
|
||||
operator==( T const& t1, T const& t2 )
|
||||
{
|
||||
return detail::eq( t1, t2 );
|
||||
}
|
||||
|
||||
template<class T> std::enable_if_t<
|
||||
has_describe_bases<T>::value && has_describe_members<T>::value, bool>
|
||||
has_describe_bases<T>::value && has_describe_members<T>::value && !std::is_union<T>::value, bool>
|
||||
operator!=( T const& t1, T const& t2 )
|
||||
{
|
||||
return !detail::eq( t1, t2 );
|
||||
}
|
||||
|
||||
template<class T> std::enable_if_t<
|
||||
has_describe_bases<T>::value && has_describe_members<T>::value, bool>
|
||||
has_describe_bases<T>::value && has_describe_members<T>::value && !std::is_union<T>::value, bool>
|
||||
operator<( T const& t1, T const& t2 )
|
||||
{
|
||||
return detail::lt( t1, t2 );
|
||||
}
|
||||
|
||||
template<class T> std::enable_if_t<
|
||||
has_describe_bases<T>::value && has_describe_members<T>::value, bool>
|
||||
has_describe_bases<T>::value && has_describe_members<T>::value && !std::is_union<T>::value, bool>
|
||||
operator>=( T const& t1, T const& t2 )
|
||||
{
|
||||
return !detail::lt( t1, t2 );
|
||||
}
|
||||
|
||||
template<class T> std::enable_if_t<
|
||||
has_describe_bases<T>::value && has_describe_members<T>::value, bool>
|
||||
has_describe_bases<T>::value && has_describe_members<T>::value && !std::is_union<T>::value, bool>
|
||||
operator>( T const& t1, T const& t2 )
|
||||
{
|
||||
return detail::lt( t2, t1 );
|
||||
}
|
||||
|
||||
template<class T> std::enable_if_t<
|
||||
has_describe_bases<T>::value && has_describe_members<T>::value, bool>
|
||||
has_describe_bases<T>::value && has_describe_members<T>::value && !std::is_union<T>::value, bool>
|
||||
operator<=( T const& t1, T const& t2 )
|
||||
{
|
||||
return !detail::lt( t2, t1 );
|
||||
}
|
||||
|
||||
template<class T, class Ch, class Tr> std::enable_if_t<
|
||||
has_describe_bases<T>::value && has_describe_members<T>::value,
|
||||
has_describe_bases<T>::value && has_describe_members<T>::value && !std::is_union<T>::value,
|
||||
std::basic_ostream<Ch, Tr>&>
|
||||
operator<<( std::basic_ostream<Ch, Tr>& os, T const& t )
|
||||
{
|
||||
|
||||
@@ -66,6 +66,9 @@ run descriptor_by_pointer_test.cpp ;
|
||||
compile unnamed_namespace_test.cpp ;
|
||||
compile unnamed_namespace_test2.cpp ;
|
||||
|
||||
run union_test.cpp ;
|
||||
run union_test2.cpp ;
|
||||
|
||||
# examples
|
||||
|
||||
obj describe_cxx14 : describe_cxx14.cpp ;
|
||||
|
||||
79
test/union_test.cpp
Normal file
79
test/union_test.cpp
Normal file
@@ -0,0 +1,79 @@
|
||||
// Copyright 2020, 2021 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/describe/members.hpp>
|
||||
#include <boost/describe/class.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/config/pragma_message.hpp>
|
||||
|
||||
#if !defined(BOOST_DESCRIBE_CXX11)
|
||||
|
||||
BOOST_PRAGMA_MESSAGE("Skipping test because C++11 is not available")
|
||||
int main() {}
|
||||
|
||||
#elif defined(__GNUC__) && __GNUC__ < 5
|
||||
|
||||
BOOST_PRAGMA_MESSAGE("Skipping test because g++ 4.8")
|
||||
int main() {}
|
||||
|
||||
#else
|
||||
|
||||
union A
|
||||
{
|
||||
int m1;
|
||||
static int m2;
|
||||
int f1() const { return m1; }
|
||||
static int f2() { return m2; }
|
||||
};
|
||||
|
||||
BOOST_DESCRIBE_STRUCT(A, (), (m1, m2, f1, f2))
|
||||
|
||||
int A::m2;
|
||||
|
||||
#if !defined(BOOST_DESCRIBE_CXX14)
|
||||
|
||||
BOOST_PRAGMA_MESSAGE("Skipping test because C++14 is not available")
|
||||
int main() {}
|
||||
|
||||
#else
|
||||
|
||||
#include <boost/mp11.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost::describe;
|
||||
using namespace boost::mp11;
|
||||
|
||||
{
|
||||
using L = describe_members<A, mod_any_access | mod_any_member>;
|
||||
|
||||
BOOST_TEST_EQ( mp_size<L>::value, 4 );
|
||||
|
||||
using D1 = mp_at_c<L, 0>;
|
||||
using D2 = mp_at_c<L, 1>;
|
||||
using D3 = mp_at_c<L, 2>;
|
||||
using D4 = mp_at_c<L, 3>;
|
||||
|
||||
BOOST_TEST( D1::pointer == &A::m1 );
|
||||
BOOST_TEST_CSTR_EQ( D1::name, "m1" );
|
||||
BOOST_TEST_EQ( D1::modifiers, mod_public );
|
||||
|
||||
BOOST_TEST( D2::pointer == &A::m2 );
|
||||
BOOST_TEST_CSTR_EQ( D2::name, "m2" );
|
||||
BOOST_TEST_EQ( D2::modifiers, mod_public | mod_static );
|
||||
|
||||
BOOST_TEST( D3::pointer == &A::f1 );
|
||||
BOOST_TEST_CSTR_EQ( D3::name, "f1" );
|
||||
BOOST_TEST_EQ( D3::modifiers, mod_public | mod_function );
|
||||
|
||||
BOOST_TEST( D4::pointer == &A::f2 );
|
||||
BOOST_TEST_CSTR_EQ( D4::name, "f2" );
|
||||
BOOST_TEST_EQ( D4::modifiers, mod_public | mod_static | mod_function );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
#endif // !defined(BOOST_DESCRIBE_CXX14)
|
||||
#endif // !defined(BOOST_DESCRIBE_CXX11)
|
||||
153
test/union_test2.cpp
Normal file
153
test/union_test2.cpp
Normal file
@@ -0,0 +1,153 @@
|
||||
// Copyright 2020, 2021 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/describe/members.hpp>
|
||||
#include <boost/describe/class.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/config/pragma_message.hpp>
|
||||
|
||||
#if !defined(BOOST_DESCRIBE_CXX11)
|
||||
|
||||
BOOST_PRAGMA_MESSAGE("Skipping test because C++11 is not available")
|
||||
int main() {}
|
||||
|
||||
#elif defined(__GNUC__) && __GNUC__ < 5
|
||||
|
||||
BOOST_PRAGMA_MESSAGE("Skipping test because g++ 4.8")
|
||||
int main() {}
|
||||
|
||||
#else
|
||||
|
||||
union A
|
||||
{
|
||||
public:
|
||||
|
||||
int m1;
|
||||
static int m2;
|
||||
int f1() const { return m1; }
|
||||
static int f2() { return m2; }
|
||||
|
||||
protected:
|
||||
|
||||
int m3;
|
||||
static int m4;
|
||||
int f3() const { return m3; }
|
||||
static int f4() { return m4; }
|
||||
|
||||
private:
|
||||
|
||||
int m5;
|
||||
static int m6;
|
||||
int f5() const { return m5; }
|
||||
static int f6() { return m6; }
|
||||
|
||||
BOOST_DESCRIBE_CLASS(A, (), (m1, m2, f1, f2), (m3, m4, f3, f4), (m5, m6, f5, f6))
|
||||
|
||||
friend int main();
|
||||
};
|
||||
|
||||
int A::m2;
|
||||
int A::m4;
|
||||
int A::m6;
|
||||
|
||||
#if !defined(BOOST_DESCRIBE_CXX14)
|
||||
|
||||
BOOST_PRAGMA_MESSAGE("Skipping test because C++14 is not available")
|
||||
int main() {}
|
||||
|
||||
#else
|
||||
|
||||
#include <boost/mp11.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost::describe;
|
||||
using namespace boost::mp11;
|
||||
|
||||
{
|
||||
using L = describe_members<A, mod_public | mod_any_member>;
|
||||
|
||||
BOOST_TEST_EQ( mp_size<L>::value, 4 );
|
||||
|
||||
using D1 = mp_at_c<L, 0>;
|
||||
using D2 = mp_at_c<L, 1>;
|
||||
using D3 = mp_at_c<L, 2>;
|
||||
using D4 = mp_at_c<L, 3>;
|
||||
|
||||
BOOST_TEST( D1::pointer == &A::m1 );
|
||||
BOOST_TEST_CSTR_EQ( D1::name, "m1" );
|
||||
BOOST_TEST_EQ( D1::modifiers, mod_public );
|
||||
|
||||
BOOST_TEST( D2::pointer == &A::m2 );
|
||||
BOOST_TEST_CSTR_EQ( D2::name, "m2" );
|
||||
BOOST_TEST_EQ( D2::modifiers, mod_public | mod_static );
|
||||
|
||||
BOOST_TEST( D3::pointer == &A::f1 );
|
||||
BOOST_TEST_CSTR_EQ( D3::name, "f1" );
|
||||
BOOST_TEST_EQ( D3::modifiers, mod_public | mod_function );
|
||||
|
||||
BOOST_TEST( D4::pointer == &A::f2 );
|
||||
BOOST_TEST_CSTR_EQ( D4::name, "f2" );
|
||||
BOOST_TEST_EQ( D4::modifiers, mod_public | mod_static | mod_function );
|
||||
}
|
||||
|
||||
{
|
||||
using L = describe_members<A, mod_protected | mod_any_member>;
|
||||
|
||||
BOOST_TEST_EQ( mp_size<L>::value, 4 );
|
||||
|
||||
using D1 = mp_at_c<L, 0>;
|
||||
using D2 = mp_at_c<L, 1>;
|
||||
using D3 = mp_at_c<L, 2>;
|
||||
using D4 = mp_at_c<L, 3>;
|
||||
|
||||
BOOST_TEST( D1::pointer == &A::m3 );
|
||||
BOOST_TEST_CSTR_EQ( D1::name, "m3" );
|
||||
BOOST_TEST_EQ( D1::modifiers, mod_protected );
|
||||
|
||||
BOOST_TEST( D2::pointer == &A::m4 );
|
||||
BOOST_TEST_CSTR_EQ( D2::name, "m4" );
|
||||
BOOST_TEST_EQ( D2::modifiers, mod_protected | mod_static );
|
||||
|
||||
BOOST_TEST( D3::pointer == &A::f3 );
|
||||
BOOST_TEST_CSTR_EQ( D3::name, "f3" );
|
||||
BOOST_TEST_EQ( D3::modifiers, mod_protected | mod_function );
|
||||
|
||||
BOOST_TEST( D4::pointer == &A::f4 );
|
||||
BOOST_TEST_CSTR_EQ( D4::name, "f4" );
|
||||
BOOST_TEST_EQ( D4::modifiers, mod_protected | mod_static | mod_function );
|
||||
}
|
||||
|
||||
{
|
||||
using L = describe_members<A, mod_private | mod_any_member>;
|
||||
|
||||
BOOST_TEST_EQ( mp_size<L>::value, 4 );
|
||||
|
||||
using D1 = mp_at_c<L, 0>;
|
||||
using D2 = mp_at_c<L, 1>;
|
||||
using D3 = mp_at_c<L, 2>;
|
||||
using D4 = mp_at_c<L, 3>;
|
||||
|
||||
BOOST_TEST( D1::pointer == &A::m5 );
|
||||
BOOST_TEST_CSTR_EQ( D1::name, "m5" );
|
||||
BOOST_TEST_EQ( D1::modifiers, mod_private );
|
||||
|
||||
BOOST_TEST( D2::pointer == &A::m6 );
|
||||
BOOST_TEST_CSTR_EQ( D2::name, "m6" );
|
||||
BOOST_TEST_EQ( D2::modifiers, mod_private | mod_static );
|
||||
|
||||
BOOST_TEST( D3::pointer == &A::f5 );
|
||||
BOOST_TEST_CSTR_EQ( D3::name, "f5" );
|
||||
BOOST_TEST_EQ( D3::modifiers, mod_private | mod_function );
|
||||
|
||||
BOOST_TEST( D4::pointer == &A::f6 );
|
||||
BOOST_TEST_CSTR_EQ( D4::name, "f6" );
|
||||
BOOST_TEST_EQ( D4::modifiers, mod_private | mod_static | mod_function );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
#endif // !defined(BOOST_DESCRIBE_CXX14)
|
||||
#endif // !defined(BOOST_DESCRIBE_CXX11)
|
||||
Reference in New Issue
Block a user