Compare commits

..

6 Commits

Author SHA1 Message Date
Peter Dimov
fc458d48c7 Change internal functions to take T** instead of T* to prevent derived to base conversions (closes #22) 2021-12-11 19:28:16 +02:00
Peter Dimov
6cc4ddafd7 Test non-described classes derived from described ones (refs #22) 2021-12-11 19:14:19 +02:00
Peter Dimov
ed1175b33a Merge branch 'maybe-unused' of https://github.com/ecatmur/describe into feature/pr-24 2021-11-17 02:22:16 +02:00
Peter Dimov
d4ebe0943e Add test for enums and classes in unnamed namespaces (refs #23) 2021-11-17 02:20:22 +02:00
Ed Catmur
1fa144623d Sprinkle [[maybe_unused]] on descriptors
Suppresses Wunused-function / Wunneeded-internal-declaration (clang) on internal-linkage types

https://github.com/boostorg/describe/issues/23
2021-11-16 21:35:33 +00:00
Peter Dimov
5032f55ac1 Update categories in libraries.json 2021-11-08 00:34:30 +02:00
14 changed files with 126 additions and 24 deletions

View File

@@ -21,7 +21,7 @@ namespace describe
namespace detail
{
template<class T> using _describe_bases = decltype( boost_base_descriptor_fn( static_cast<T*>(0) ) );
template<class T> using _describe_bases = decltype( boost_base_descriptor_fn( static_cast<T**>(0) ) );
template<unsigned M> struct base_filter
{

View File

@@ -54,17 +54,17 @@ namespace describe
#define BOOST_DESCRIBE_PRIVATE_MEMBERS_(...) BOOST_DESCRIBE_PRIVATE_MEMBERS(__VA_ARGS__)
#define BOOST_DESCRIBE_CLASS(C, Bases, Public, Protected, Private) \
friend BOOST_DESCRIBE_BASES_(C BOOST_DESCRIBE_PP_UNPACK Bases) \
friend BOOST_DESCRIBE_PUBLIC_MEMBERS_(C BOOST_DESCRIBE_PP_UNPACK Public) \
friend BOOST_DESCRIBE_PROTECTED_MEMBERS_(C BOOST_DESCRIBE_PP_UNPACK Protected) \
friend BOOST_DESCRIBE_PRIVATE_MEMBERS_(C BOOST_DESCRIBE_PP_UNPACK Private)
BOOST_DESCRIBE_MAYBE_UNUSED friend BOOST_DESCRIBE_BASES_(C BOOST_DESCRIBE_PP_UNPACK Bases) \
BOOST_DESCRIBE_MAYBE_UNUSED friend BOOST_DESCRIBE_PUBLIC_MEMBERS_(C BOOST_DESCRIBE_PP_UNPACK Public) \
BOOST_DESCRIBE_MAYBE_UNUSED friend BOOST_DESCRIBE_PROTECTED_MEMBERS_(C BOOST_DESCRIBE_PP_UNPACK Protected) \
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"); \
BOOST_DESCRIBE_BASES_(C BOOST_DESCRIBE_PP_UNPACK Bases) \
BOOST_DESCRIBE_PUBLIC_MEMBERS_(C BOOST_DESCRIBE_PP_UNPACK Members) \
BOOST_DESCRIBE_PROTECTED_MEMBERS_(C) \
BOOST_DESCRIBE_PRIVATE_MEMBERS_(C)
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) \
BOOST_DESCRIBE_MAYBE_UNUSED BOOST_DESCRIBE_PRIVATE_MEMBERS_(C)
#endif

View File

@@ -37,12 +37,12 @@ template<class... T> auto base_descriptor_fn_impl( int, T... )
#if defined(_MSC_VER) && !defined(__clang__)
#define BOOST_DESCRIBE_BASES(C, ...) inline auto boost_base_descriptor_fn( C * ) \
#define BOOST_DESCRIBE_BASES(C, ...) inline auto boost_base_descriptor_fn( C** ) \
{ return boost::describe::detail::base_descriptor_fn_impl( 0 BOOST_DESCRIBE_PP_FOR_EACH(BOOST_DESCRIBE_BASE_IMPL, C, __VA_ARGS__) ); }
#else
#define BOOST_DESCRIBE_BASES(C, ...) inline auto boost_base_descriptor_fn( C * ) \
#define BOOST_DESCRIBE_BASES(C, ...) inline auto boost_base_descriptor_fn( C** ) \
{ return boost::describe::detail::base_descriptor_fn_impl( 0 BOOST_DESCRIBE_PP_FOR_EACH(BOOST_DESCRIBE_BASE_IMPL, C, ##__VA_ARGS__) ); }
#endif

View File

@@ -27,4 +27,12 @@
# define BOOST_DESCRIBE_CONSTEXPR_OR_CONST const
#endif
#define BOOST_DESCRIBE_MAYBE_UNUSED
#if defined(__has_cpp_attribute)
# if __has_cpp_attribute(maybe_unused)
# undef BOOST_DESCRIBE_MAYBE_UNUSED
# define BOOST_DESCRIBE_MAYBE_UNUSED [[maybe_unused]]
# endif
#endif
#endif // #ifndef BOOST_DESCRIBE_DETAIL_CONFIG_HPP_INCLUDED

View File

@@ -53,24 +53,24 @@ template<class C, class F> constexpr auto mfn( F * p ) { return p; }
#if defined(_MSC_VER) && !defined(__clang__)
#define BOOST_DESCRIBE_PUBLIC_MEMBERS(C, ...) inline auto boost_public_member_descriptor_fn( C * ) \
#define BOOST_DESCRIBE_PUBLIC_MEMBERS(C, ...) inline auto boost_public_member_descriptor_fn( C** ) \
{ return boost::describe::detail::member_descriptor_fn_impl<boost::describe::mod_public>( 0 BOOST_DESCRIBE_PP_FOR_EACH(BOOST_DESCRIBE_MEMBER_IMPL, C, __VA_ARGS__) ); }
#define BOOST_DESCRIBE_PROTECTED_MEMBERS(C, ...) inline auto boost_protected_member_descriptor_fn( C * ) \
#define BOOST_DESCRIBE_PROTECTED_MEMBERS(C, ...) inline auto boost_protected_member_descriptor_fn( C** ) \
{ return boost::describe::detail::member_descriptor_fn_impl<boost::describe::mod_protected>( 0 BOOST_DESCRIBE_PP_FOR_EACH(BOOST_DESCRIBE_MEMBER_IMPL, C, __VA_ARGS__) ); }
#define BOOST_DESCRIBE_PRIVATE_MEMBERS(C, ...) inline auto boost_private_member_descriptor_fn( C * ) \
#define BOOST_DESCRIBE_PRIVATE_MEMBERS(C, ...) inline auto boost_private_member_descriptor_fn( C** ) \
{ return boost::describe::detail::member_descriptor_fn_impl<boost::describe::mod_private>( 0 BOOST_DESCRIBE_PP_FOR_EACH(BOOST_DESCRIBE_MEMBER_IMPL, C, __VA_ARGS__) ); }
#else
#define BOOST_DESCRIBE_PUBLIC_MEMBERS(C, ...) inline auto boost_public_member_descriptor_fn( C * ) \
#define BOOST_DESCRIBE_PUBLIC_MEMBERS(C, ...) inline auto boost_public_member_descriptor_fn( C** ) \
{ return boost::describe::detail::member_descriptor_fn_impl<boost::describe::mod_public>( 0 BOOST_DESCRIBE_PP_FOR_EACH(BOOST_DESCRIBE_MEMBER_IMPL, C, ##__VA_ARGS__) ); }
#define BOOST_DESCRIBE_PROTECTED_MEMBERS(C, ...) inline auto boost_protected_member_descriptor_fn( C * ) \
#define BOOST_DESCRIBE_PROTECTED_MEMBERS(C, ...) inline auto boost_protected_member_descriptor_fn( C** ) \
{ return boost::describe::detail::member_descriptor_fn_impl<boost::describe::mod_protected>( 0 BOOST_DESCRIBE_PP_FOR_EACH(BOOST_DESCRIBE_MEMBER_IMPL, C, ##__VA_ARGS__) ); }
#define BOOST_DESCRIBE_PRIVATE_MEMBERS(C, ...) inline auto boost_private_member_descriptor_fn( C * ) \
#define BOOST_DESCRIBE_PRIVATE_MEMBERS(C, ...) inline auto boost_private_member_descriptor_fn( C** ) \
{ return boost::describe::detail::member_descriptor_fn_impl<boost::describe::mod_private>( 0 BOOST_DESCRIBE_PP_FOR_EACH(BOOST_DESCRIBE_MEMBER_IMPL, C, ##__VA_ARGS__) ); }
#endif

View File

@@ -42,7 +42,7 @@ template<class... T> auto enum_descriptor_fn_impl( int, T... )
}
#define BOOST_DESCRIBE_ENUM_BEGIN(E) \
inline auto boost_enum_descriptor_fn( E* ) \
inline auto boost_enum_descriptor_fn( E** ) \
{ return boost::describe::detail::enum_descriptor_fn_impl( 0
#define BOOST_DESCRIBE_ENUM_ENTRY(E, e) , []{ struct _boost_desc { \
@@ -71,13 +71,13 @@ template<class... T> auto enum_descriptor_fn_impl( int, T... )
#define BOOST_DESCRIBE_ENUM(E, ...) \
static_assert(std::is_enum<E>::value, "BOOST_DESCRIBE_ENUM should only be used with enums"); \
BOOST_DESCRIBE_ENUM_BEGIN(E) \
BOOST_DESCRIBE_MAYBE_UNUSED BOOST_DESCRIBE_ENUM_BEGIN(E) \
BOOST_DESCRIBE_PP_FOR_EACH(BOOST_DESCRIBE_ENUM_ENTRY, E, ##__VA_ARGS__) \
BOOST_DESCRIBE_ENUM_END(E)
#define BOOST_DESCRIBE_NESTED_ENUM(E, ...) \
static_assert(std::is_enum<E>::value, "BOOST_DESCRIBE_NESTED_ENUM should only be used with enums"); \
friend BOOST_DESCRIBE_ENUM_BEGIN(E) \
BOOST_DESCRIBE_MAYBE_UNUSED friend BOOST_DESCRIBE_ENUM_BEGIN(E) \
BOOST_DESCRIBE_PP_FOR_EACH(BOOST_DESCRIBE_ENUM_ENTRY, E, ##__VA_ARGS__) \
BOOST_DESCRIBE_ENUM_END(E)

View File

@@ -19,7 +19,7 @@ namespace describe
// describe_enumerators<E>
template<class E> using describe_enumerators = decltype( boost_enum_descriptor_fn( static_cast<E*>(0) ) );
template<class E> using describe_enumerators = decltype( boost_enum_descriptor_fn( static_cast<E**>(0) ) );
// has_describe_enumerators<E>

View File

@@ -29,9 +29,9 @@ namespace detail
// _describe_members<T>
template<class T> using _describe_public_members = decltype( boost_public_member_descriptor_fn( static_cast<T*>(0) ) );
template<class T> using _describe_protected_members = decltype( boost_protected_member_descriptor_fn( static_cast<T*>(0) ) );
template<class T> using _describe_private_members = decltype( boost_private_member_descriptor_fn( static_cast<T*>(0) ) );
template<class T> using _describe_public_members = decltype( boost_public_member_descriptor_fn( static_cast<T**>(0) ) );
template<class T> using _describe_protected_members = decltype( boost_protected_member_descriptor_fn( static_cast<T**>(0) ) );
template<class T> using _describe_private_members = decltype( boost_private_member_descriptor_fn( static_cast<T**>(0) ) );
template<class T> using _describe_members = mp11::mp_append<_describe_public_members<T>, _describe_protected_members<T>, _describe_private_members<T>>;

View File

@@ -9,6 +9,7 @@
],
"description": "A C++14 reflection library.",
"category": [
"Emulation",
"Metaprogramming"
]
}

View File

@@ -63,6 +63,9 @@ run operator_lt_test.cpp ;
run descriptor_by_name_test.cpp ;
run descriptor_by_pointer_test.cpp ;
compile unnamed_namespace_test.cpp ;
compile unnamed_namespace_test2.cpp ;
# examples
obj describe_cxx14 : describe_cxx14.cpp ;

View File

@@ -27,6 +27,9 @@ struct X3 {};
class X4 {};
union X5 {};
struct X6: X1 {};
struct X7: X2 {};
int main()
{
using boost::describe::has_describe_bases;
@@ -46,6 +49,8 @@ int main()
BOOST_TEST_TRAIT_FALSE((has_describe_bases<X3>));
BOOST_TEST_TRAIT_FALSE((has_describe_bases<X4>));
BOOST_TEST_TRAIT_FALSE((has_describe_bases<X5>));
BOOST_TEST_TRAIT_FALSE((has_describe_bases<X6>));
BOOST_TEST_TRAIT_FALSE((has_describe_bases<X7>));
BOOST_TEST_TRAIT_FALSE((has_describe_bases<int>));
BOOST_TEST_TRAIT_FALSE((has_describe_bases<void>));

View File

@@ -27,6 +27,9 @@ struct X3 {};
class X4 {};
union X5 {};
struct X6: X1 {};
struct X7: X2 {};
int main()
{
using boost::describe::has_describe_members;
@@ -46,6 +49,8 @@ int main()
BOOST_TEST_TRAIT_FALSE((has_describe_members<X3>));
BOOST_TEST_TRAIT_FALSE((has_describe_members<X4>));
BOOST_TEST_TRAIT_FALSE((has_describe_members<X5>));
BOOST_TEST_TRAIT_FALSE((has_describe_members<X6>));
BOOST_TEST_TRAIT_FALSE((has_describe_members<X7>));
BOOST_TEST_TRAIT_FALSE((has_describe_members<int>));
BOOST_TEST_TRAIT_FALSE((has_describe_members<void>));

View File

@@ -0,0 +1,35 @@
// Copyright 2021 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/describe.hpp>
#if !defined(BOOST_DESCRIBE_CXX14)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Skipping test because C++14 is not available")
#else
namespace
{
enum E { v };
BOOST_DESCRIBE_ENUM(E, v)
struct S
{
};
BOOST_DESCRIBE_STRUCT(S, (), ())
class C
{
BOOST_DESCRIBE_CLASS(C, (), (), (), ())
};
} // namespace
#endif // !defined(BOOST_DESCRIBE_CXX14)

View File

@@ -0,0 +1,45 @@
// Copyright 2021 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/describe.hpp>
#if !defined(BOOST_DESCRIBE_CXX14)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Skipping test because C++14 is not available")
#else
namespace
{
enum E { v };
BOOST_DESCRIBE_ENUM(E, v)
struct X
{
};
BOOST_DESCRIBE_STRUCT(X, (), ())
class Y
{
BOOST_DESCRIBE_CLASS(Y, (), (), (), ())
};
} // namespace
using namespace boost::describe;
using L1 = describe_enumerators<E>;
using L2 = describe_bases<X, mod_any_access>;
using L3 = describe_members<X, mod_any_access>;
using L4 = describe_bases<Y, mod_any_access>;
using L5 = describe_members<Y, mod_any_access>;
#endif // !defined(BOOST_DESCRIBE_CXX14)