mirror of
https://github.com/boostorg/describe.git
synced 2026-01-21 04:42:45 +00:00
Compare commits
14 Commits
feature/en
...
feature/is
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
62c032ff22 | ||
|
|
bef1e45cb0 | ||
|
|
92afba2c39 | ||
|
|
031c55b392 | ||
|
|
36c52dcbd6 | ||
|
|
4ca49a6af2 | ||
|
|
1bf6dddac0 | ||
|
|
39cf63cee1 | ||
|
|
5ebca2615a | ||
|
|
7f36a2c798 | ||
|
|
564f849629 | ||
|
|
ed26d4c495 | ||
|
|
8aa347b171 | ||
|
|
acf14803ba |
8
.github/workflows/ci.yml
vendored
8
.github/workflows/ci.yml
vendored
@@ -159,6 +159,11 @@ jobs:
|
||||
cxxstd: "14,17,latest"
|
||||
addrmd: 32,64
|
||||
os: windows-2019
|
||||
- toolset: msvc-14.2
|
||||
cxxstd: "14,17,latest"
|
||||
addrmd: 32,64
|
||||
cxxflags: "-Zc:preprocessor"
|
||||
os: windows-2019
|
||||
- toolset: gcc
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
addrmd: 64
|
||||
@@ -195,4 +200,5 @@ jobs:
|
||||
shell: cmd
|
||||
run: |
|
||||
cd ../boost-root
|
||||
b2 -j3 libs/%LIBRARY%/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release
|
||||
if not "${{matrix.cxxflags}}" == "" set CXXFLAGS=cxxflags=${{matrix.cxxflags}}
|
||||
b2 -j3 libs/%LIBRARY%/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} %CXXFLAGS% variant=debug,release
|
||||
|
||||
@@ -7,8 +7,7 @@ and usage examples.
|
||||
|
||||
## Supported Compilers
|
||||
|
||||
* GCC 5 or later with `-std=gnu++14` or above
|
||||
* GCC 8 or later with `-std=c++14` or above
|
||||
* GCC 5 or later with `-std=c++14` or above
|
||||
* Clang 3.6 or later with `-std=c++14` or above
|
||||
* Visual Studio 2015, 2017, 2019
|
||||
|
||||
|
||||
@@ -31,6 +31,11 @@ environment:
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
TOOLSET: clang-win
|
||||
CXXSTD: 14,17,latest
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
TOOLSET: msvc-14.2
|
||||
CXXSTD: 14,17,latest
|
||||
ADDRMD: 32,64
|
||||
CXXFLAGS: -Zc:preprocessor
|
||||
|
||||
install:
|
||||
- set BOOST_BRANCH=develop
|
||||
@@ -49,4 +54,5 @@ build: off
|
||||
test_script:
|
||||
- if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
|
||||
- if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD%
|
||||
- b2 -j3 libs/describe/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release embed-manifest-via=linker
|
||||
- if not "%CXXFLAGS%" == "" set CXXFLAGS=cxxflags=%CXXFLAGS%
|
||||
- b2 -j3 libs/describe/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% %CXXFLAGS% variant=debug,release embed-manifest-via=linker
|
||||
|
||||
@@ -10,6 +10,8 @@ Peter Dimov
|
||||
:toclevels: 4
|
||||
:idprefix:
|
||||
:docinfo: private-footer
|
||||
:source-highlighter: rouge
|
||||
:source-language: c++
|
||||
|
||||
:leveloffset: +1
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@ https://www.boost.org/LICENSE_1_0.txt
|
||||
# Describing Class Types
|
||||
:idprefix: classes_
|
||||
|
||||
## Class Types with Public Members
|
||||
|
||||
If you have a `struct`
|
||||
|
||||
```
|
||||
@@ -31,8 +33,15 @@ It takes three arguments: the `struct` name, a list of base classes
|
||||
(empty in our example), and a list of (public) members by name (this includes
|
||||
both data members and member functions.)
|
||||
|
||||
To describe a class type with protected or private members, use the
|
||||
`BOOST_DESCRIBE_CLASS` macro instead, placing it _inside the class_.
|
||||
Since `BOOST_DESCRIBE_STRUCT` is placed outside the type, it's non-intrisive,
|
||||
does not require access to the definition, and can therefore be used to describe
|
||||
third-party types or types defined in system headers.
|
||||
|
||||
## Class Types with Protected or Private Members
|
||||
|
||||
To describe a class type, use the `BOOST_DESCRIBE_CLASS` macro instead, placing
|
||||
it _inside the class_. This gives the macro access to the protected and private
|
||||
members, but is intrusive and requires access to the definition.
|
||||
|
||||
```
|
||||
class Y: private X
|
||||
@@ -121,3 +130,55 @@ For an example of how to use the base and data member descriptors, see
|
||||
|
||||
For an example of how to use member function descriptors, see
|
||||
<<example_json_rpc>>.
|
||||
|
||||
## Overloaded Member Functions
|
||||
|
||||
To describe an overloaded member function, you will need to resort to
|
||||
a more complicated syntax, as simply listing its name (say, `f`) will make
|
||||
the library attempt to form a member pointer with `&X::f`, which would fail
|
||||
because it's not clear to which `f` this expression refers.
|
||||
|
||||
To disambiguate, precede the function name with the type of the function, in
|
||||
parentheses, as shown in the following example:
|
||||
|
||||
```
|
||||
struct X
|
||||
{
|
||||
int f();
|
||||
int f() const;
|
||||
void f( int x );
|
||||
};
|
||||
|
||||
BOOST_DESCRIBE_STRUCT(X, (), (
|
||||
(int ()) f,
|
||||
(int () const) f,
|
||||
(void (int)) f
|
||||
))
|
||||
```
|
||||
|
||||
The type of the function is the same as its declaration, without the name.
|
||||
|
||||
Be sure to retain the space between the parenthesized function type and its name,
|
||||
because omitting it will compile happily on GCC and Clang but will lead to
|
||||
inscrutable errors on MSVC due to its nonstandard preprocessor.
|
||||
|
||||
Pay attention to the proper placement of the parentheses, because a mistake there
|
||||
will also lead to hard to decipher compiler errors, on all compilers.
|
||||
|
||||
The same technique also works with `BOOST_DESCRIBE_CLASS`, and with static member
|
||||
functions:
|
||||
|
||||
```
|
||||
class Y
|
||||
{
|
||||
public:
|
||||
|
||||
static void f( int x );
|
||||
static void f( int x, int y );
|
||||
|
||||
BOOST_DESCRIBE_CLASS(Y, (), ((void (int)) f, (void (int, int)) f), (), ())
|
||||
};
|
||||
```
|
||||
|
||||
The case where a member function and a static member function have the same name
|
||||
and the same function type is currently not supported.
|
||||
|
||||
@@ -14,8 +14,7 @@ https://boost.org/libs/mp11[Boost.Mp11].
|
||||
|
||||
## Supported Compilers
|
||||
|
||||
* GCC 5 or later with `-std=gnu++14` or above
|
||||
* GCC 8 or later with `-std=c++14` or above
|
||||
* GCC 5 or later with `-std=c++14` or above
|
||||
* Clang 3.6 or later with `-std=c++14` or above
|
||||
* Visual Studio 2015, 2017, 2019
|
||||
|
||||
@@ -31,8 +30,6 @@ This implementation has the following limitations:
|
||||
* Protected base classes cannot be distinguished from private
|
||||
base classes when the described class is final, and are considered
|
||||
private.
|
||||
* Overloaded member functions are not supported. Member names
|
||||
must be unique within the class.
|
||||
* Bitfields are not supported. It's not possible to form a pointer
|
||||
to member to a bitfield.
|
||||
* Reference members are not supported. It's not possible to form a
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -16,6 +16,7 @@
|
||||
|
||||
#include <boost/describe/detail/bases.hpp>
|
||||
#include <boost/describe/detail/members.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
@@ -33,6 +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"); \
|
||||
BOOST_DESCRIBE_BASES(C, BOOST_DESCRIBE_PP_UNPACK Bases) \
|
||||
BOOST_DESCRIBE_PUBLIC_MEMBERS(C, BOOST_DESCRIBE_PP_UNPACK Members) \
|
||||
BOOST_DESCRIBE_PROTECTED_MEMBERS(C) \
|
||||
@@ -58,6 +60,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"); \
|
||||
BOOST_DESCRIBE_BASES_(C BOOST_DESCRIBE_PP_UNPACK Bases) \
|
||||
BOOST_DESCRIBE_PUBLIC_MEMBERS_(C BOOST_DESCRIBE_PP_UNPACK Members) \
|
||||
BOOST_DESCRIBE_PROTECTED_MEMBERS_(C) \
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include <boost/describe/modifiers.hpp>
|
||||
#include <boost/describe/detail/pp_for_each.hpp>
|
||||
#include <boost/describe/detail/pp_utilities.hpp>
|
||||
#include <boost/describe/detail/list.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
@@ -43,9 +44,12 @@ template<unsigned M, class... T> auto member_descriptor_fn_impl( int, T... )
|
||||
return list<member_descriptor<T, M>...>();
|
||||
}
|
||||
|
||||
template<class C, class F> constexpr auto mfn( F C::* p ) { return p; }
|
||||
template<class C, class F> constexpr auto mfn( F * p ) { return p; }
|
||||
|
||||
#define BOOST_DESCRIBE_MEMBER_IMPL(C, m) , []{ struct _boost_desc { \
|
||||
static constexpr auto pointer() noexcept { return &C::m; } \
|
||||
static constexpr auto name() noexcept { return #m; } }; return _boost_desc(); }()
|
||||
static constexpr auto pointer() noexcept { return BOOST_DESCRIBE_PP_POINTER(C, m); } \
|
||||
static constexpr auto name() noexcept { return BOOST_DESCRIBE_PP_NAME(m); } }; return _boost_desc(); }()
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
|
||||
|
||||
@@ -45,4 +45,48 @@
|
||||
#define BOOST_DESCRIBE_PP_CALL_I_0(F, a, x) F(a, x)
|
||||
#define BOOST_DESCRIBE_PP_CALL_I_1(F, a, x)
|
||||
|
||||
#define BOOST_DESCRIBE_PP_PARSE(x) BOOST_DESCRIBE_PP_CAT(BOOST_DESCRIBE_PP_PARSE_I_, BOOST_DESCRIBE_PP_PARSE_II x)
|
||||
#define BOOST_DESCRIBE_PP_PARSE_II(...) 0, (__VA_ARGS__),
|
||||
#define BOOST_DESCRIBE_PP_PARSE_I_BOOST_DESCRIBE_PP_PARSE_II 0, ~,
|
||||
#define BOOST_DESCRIBE_PP_PARSE_I_0 1
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
|
||||
#define BOOST_DESCRIBE_PP_NAME(x) BOOST_DESCRIBE_PP_NAME_I(BOOST_DESCRIBE_PP_PARSE(x))
|
||||
#define BOOST_DESCRIBE_PP_NAME_I(x) BOOST_DESCRIBE_PP_NAME_II((x))
|
||||
#define BOOST_DESCRIBE_PP_NAME_II(x) BOOST_DESCRIBE_PP_NAME_III x
|
||||
#define BOOST_DESCRIBE_PP_NAME_III(x, y, z) #z
|
||||
|
||||
#else
|
||||
|
||||
#define BOOST_DESCRIBE_PP_NAME(x) BOOST_DESCRIBE_PP_NAME_I(BOOST_DESCRIBE_PP_PARSE(x))
|
||||
#define BOOST_DESCRIBE_PP_NAME_I(x) BOOST_DESCRIBE_PP_NAME_II(x)
|
||||
#define BOOST_DESCRIBE_PP_NAME_II(x, y, z) #z
|
||||
|
||||
#endif
|
||||
|
||||
// template<class C, class F> constexpr auto mfn( F C::* p ) { return p; }
|
||||
// template<class C, class F> constexpr auto mfn( F * p ) { return p; }
|
||||
|
||||
#define BOOST_DESCRIBE_PP_POINTER(C, x) BOOST_DESCRIBE_PP_POINTER_I(C, BOOST_DESCRIBE_PP_PARSE(x))
|
||||
|
||||
#define BOOST_DESCRIBE_PP_EXPAND_V(...) __VA_ARGS__
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
|
||||
#define BOOST_DESCRIBE_PP_POINTER_I(C, x) BOOST_DESCRIBE_PP_POINTER_II((C, x))
|
||||
#define BOOST_DESCRIBE_PP_POINTER_II(x) BOOST_DESCRIBE_PP_POINTER_III x
|
||||
#define BOOST_DESCRIBE_PP_POINTER_III(C, x, y, z) BOOST_DESCRIBE_PP_POINTER_III_##x(C, y, z)
|
||||
#define BOOST_DESCRIBE_PP_POINTER_III_0(C, y, z) &C::z
|
||||
#define BOOST_DESCRIBE_PP_POINTER_III_1(C, y, z) ::boost::describe::detail::mfn<C, BOOST_DESCRIBE_PP_EXPAND_V y>(&C::z)
|
||||
|
||||
#else
|
||||
|
||||
#define BOOST_DESCRIBE_PP_POINTER_I(C, x) BOOST_DESCRIBE_PP_POINTER_II(C, x)
|
||||
#define BOOST_DESCRIBE_PP_POINTER_II(C, x, y, z) BOOST_DESCRIBE_PP_POINTER_III_##x(C, y, z)
|
||||
#define BOOST_DESCRIBE_PP_POINTER_III_0(C, y, z) &C::z
|
||||
#define BOOST_DESCRIBE_PP_POINTER_III_1(C, y, z) ::boost::describe::detail::mfn<C, BOOST_DESCRIBE_PP_EXPAND_V y>(&C::z)
|
||||
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_DESCRIBE_DETAIL_PP_UTILITIES_HPP_INCLUDED
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/describe/detail/pp_for_each.hpp>
|
||||
#include <boost/describe/detail/list.hpp>
|
||||
#include <boost/describe/detail/config.hpp>
|
||||
|
||||
#if !defined(BOOST_DESCRIBE_CXX14)
|
||||
@@ -15,6 +13,10 @@
|
||||
|
||||
#else
|
||||
|
||||
#include <boost/describe/detail/pp_for_each.hpp>
|
||||
#include <boost/describe/detail/list.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace describe
|
||||
@@ -53,6 +55,7 @@ template<class... T> auto enum_descriptor_fn_impl( int, T... )
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
|
||||
#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_PP_FOR_EACH(BOOST_DESCRIBE_ENUM_ENTRY, E, __VA_ARGS__) \
|
||||
BOOST_DESCRIBE_ENUM_END(E)
|
||||
@@ -60,6 +63,7 @@ template<class... T> auto enum_descriptor_fn_impl( int, T... )
|
||||
#else
|
||||
|
||||
#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_PP_FOR_EACH(BOOST_DESCRIBE_ENUM_ENTRY, E, ##__VA_ARGS__) \
|
||||
BOOST_DESCRIBE_ENUM_END(E)
|
||||
|
||||
10
test/Jamfile
10
test/Jamfile
@@ -18,6 +18,9 @@ run pp_for_each_test.cpp ;
|
||||
run pp_is_paren_test.cpp ;
|
||||
run pp_is_empty_test.cpp ;
|
||||
run pp_call_test.cpp ;
|
||||
run pp_parse_test.cpp ;
|
||||
run pp_name_test.cpp ;
|
||||
run pp_pointer_test.cpp ;
|
||||
|
||||
run enumerators_test.cpp ;
|
||||
run empty_enum_test.cpp ;
|
||||
@@ -33,15 +36,20 @@ run members_test4.cpp ;
|
||||
run members_test5.cpp ;
|
||||
run members_test6.cpp ;
|
||||
run members_test7.cpp : : : <toolset>msvc-14.0:<build>no ;
|
||||
run overloaded_test.cpp ;
|
||||
run overloaded_test2.cpp ;
|
||||
|
||||
compile test_d_type.cpp ;
|
||||
|
||||
compile-fail enum_struct_fail.cpp ;
|
||||
compile-fail struct_enum_fail.cpp ;
|
||||
|
||||
obj describe_cxx14 : describe_cxx14.cpp ;
|
||||
explicit describe_cxx14 ;
|
||||
|
||||
local CXX14 = [ check-target-builds describe_cxx14 describe_cxx14 : : <build>no ] ;
|
||||
|
||||
local JSON = <library>/boost//json/<warnings>off "<toolset>msvc-14.0:<build>no" ;
|
||||
local JSON = <library>/boost//json/<warnings>off "<toolset>msvc-14.0:<build>no" "<toolset>msvc-14.2:<cxxflags>-wd5104" ;
|
||||
local SERIALIZATION = <library>/boost//serialization/<warnings>off "-<toolset>clang:<warnings-as-errors>on" ;
|
||||
|
||||
run ../example/printing_enums_ct.cpp : : : $(CXX14) ;
|
||||
|
||||
16
test/enum_struct_fail.cpp
Normal file
16
test/enum_struct_fail.cpp
Normal file
@@ -0,0 +1,16 @@
|
||||
// Copyright 2021 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/describe/class.hpp>
|
||||
|
||||
#if !defined(BOOST_DESCRIBE_CXX14)
|
||||
|
||||
#error "Skipping test because C++14 is not available"
|
||||
|
||||
#else
|
||||
|
||||
enum E1 {};
|
||||
BOOST_DESCRIBE_STRUCT(E1, (), ())
|
||||
|
||||
#endif // !defined(BOOST_DESCRIBE_CXX14)
|
||||
@@ -40,7 +40,7 @@ private:
|
||||
BOOST_DESCRIBE_CLASS(A2, (), (m1), (m2), (m3))
|
||||
};
|
||||
|
||||
struct B: public A1, private A2
|
||||
class A3
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -54,7 +54,24 @@ private:
|
||||
|
||||
int m3;
|
||||
|
||||
BOOST_DESCRIBE_CLASS(B, (A1, A2), (m1), (m2), (m3))
|
||||
BOOST_DESCRIBE_CLASS(A3, (), (m1), (m2), (m3))
|
||||
};
|
||||
|
||||
struct B: public A1, protected A2, private A3
|
||||
{
|
||||
public:
|
||||
|
||||
int m1;
|
||||
|
||||
protected:
|
||||
|
||||
int m2;
|
||||
|
||||
private:
|
||||
|
||||
int m3;
|
||||
|
||||
BOOST_DESCRIBE_CLASS(B, (A1, A2, A3), (m1), (m2), (m3))
|
||||
};
|
||||
|
||||
#if !defined(BOOST_DESCRIBE_CXX14)
|
||||
@@ -93,50 +110,65 @@ int main()
|
||||
{
|
||||
using L = describe_members<B, mod_protected | mod_inherited | mod_hidden>;
|
||||
|
||||
BOOST_TEST_EQ( mp_size<L>::value, 2 );
|
||||
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 == &B::A1::m2 );
|
||||
BOOST_TEST_CSTR_EQ( D1::name, "m2" );
|
||||
BOOST_TEST_EQ( D1::modifiers, mod_protected | mod_inherited | mod_hidden );
|
||||
|
||||
// BOOST_TEST( D2::pointer == &B::m2 );
|
||||
BOOST_TEST_CSTR_EQ( D2::name, "m2" );
|
||||
BOOST_TEST_EQ( D2::modifiers, mod_protected );
|
||||
// BOOST_TEST( D2::pointer == &B::A2::m1 );
|
||||
BOOST_TEST_CSTR_EQ( D2::name, "m1" );
|
||||
BOOST_TEST_EQ( D2::modifiers, mod_protected | mod_inherited | mod_hidden );
|
||||
|
||||
// BOOST_TEST( D3::pointer == &B::A2::m2 );
|
||||
BOOST_TEST_CSTR_EQ( D3::name, "m2" );
|
||||
BOOST_TEST_EQ( D3::modifiers, mod_protected | mod_inherited | mod_hidden );
|
||||
|
||||
// BOOST_TEST( D4::pointer == &B::m2 );
|
||||
BOOST_TEST_CSTR_EQ( D4::name, "m2" );
|
||||
BOOST_TEST_EQ( D4::modifiers, mod_protected );
|
||||
}
|
||||
|
||||
{
|
||||
using L = describe_members<B, mod_private | mod_inherited | mod_hidden>;
|
||||
|
||||
BOOST_TEST_EQ( mp_size<L>::value, 5 );
|
||||
BOOST_TEST_EQ( mp_size<L>::value, 6 );
|
||||
|
||||
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>;
|
||||
using D5 = mp_at_c<L, 4>;
|
||||
using D6 = mp_at_c<L, 5>;
|
||||
|
||||
// BOOST_TEST( D1::pointer == &B::A1::m3 );
|
||||
BOOST_TEST_CSTR_EQ( D1::name, "m3" );
|
||||
BOOST_TEST_EQ( D1::modifiers, mod_private | mod_inherited | mod_hidden );
|
||||
|
||||
// BOOST_TEST( D2::pointer == &B::A2::m1 );
|
||||
BOOST_TEST_CSTR_EQ( D2::name, "m1" );
|
||||
// BOOST_TEST( D2::pointer == &B::A2::m3 );
|
||||
BOOST_TEST_CSTR_EQ( D2::name, "m3" );
|
||||
BOOST_TEST_EQ( D2::modifiers, mod_private | mod_inherited | mod_hidden );
|
||||
|
||||
// BOOST_TEST( D3::pointer == &B::A2::m2 );
|
||||
BOOST_TEST_CSTR_EQ( D3::name, "m2" );
|
||||
// BOOST_TEST( D3::pointer == &B::A3::m1 );
|
||||
BOOST_TEST_CSTR_EQ( D3::name, "m1" );
|
||||
BOOST_TEST_EQ( D3::modifiers, mod_private | mod_inherited | mod_hidden );
|
||||
|
||||
// BOOST_TEST( D4::pointer == &B::A2::m3 );
|
||||
BOOST_TEST_CSTR_EQ( D4::name, "m3" );
|
||||
// BOOST_TEST( D4::pointer == &B::A3::m2 );
|
||||
BOOST_TEST_CSTR_EQ( D4::name, "m2" );
|
||||
BOOST_TEST_EQ( D4::modifiers, mod_private | mod_inherited | mod_hidden );
|
||||
|
||||
// BOOST_TEST( D5::pointer == &B::m3 );
|
||||
// BOOST_TEST( D5::pointer == &B::A3::m3 );
|
||||
BOOST_TEST_CSTR_EQ( D5::name, "m3" );
|
||||
BOOST_TEST_EQ( D5::modifiers, mod_private );
|
||||
BOOST_TEST_EQ( D5::modifiers, mod_private | mod_inherited | mod_hidden );
|
||||
|
||||
// BOOST_TEST( D6::pointer == &B::m3 );
|
||||
BOOST_TEST_CSTR_EQ( D6::name, "m3" );
|
||||
BOOST_TEST_EQ( D6::modifiers, mod_private );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
|
||||
82
test/overloaded_test.cpp
Normal file
82
test/overloaded_test.cpp
Normal file
@@ -0,0 +1,82 @@
|
||||
// Copyright 2020 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>
|
||||
|
||||
struct X
|
||||
{
|
||||
int f() { return 1; }
|
||||
int f() const { return 2; }
|
||||
|
||||
static int f( int x ) { return x; }
|
||||
static int f( int x, int y ) { return x + y; }
|
||||
};
|
||||
|
||||
BOOST_DESCRIBE_STRUCT(X, (), (
|
||||
(int ()) f,
|
||||
(int () const) f,
|
||||
(int (int)) f,
|
||||
(int (int, int)) f
|
||||
))
|
||||
|
||||
#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
|
||||
|
||||
#include <boost/mp11.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost::describe;
|
||||
using namespace boost::mp11;
|
||||
|
||||
{
|
||||
using L = describe_members<X, mod_any_access | mod_function>;
|
||||
|
||||
BOOST_TEST_EQ( mp_size<L>::value, 2 );
|
||||
|
||||
using D1 = mp_at_c<L, 0>;
|
||||
using D2 = mp_at_c<L, 1>;
|
||||
|
||||
X x;
|
||||
|
||||
BOOST_TEST_EQ( (x.*D1::pointer)(), 1 );
|
||||
BOOST_TEST_CSTR_EQ( D1::name, "f" );
|
||||
BOOST_TEST_EQ( D1::modifiers, mod_public | mod_function );
|
||||
|
||||
BOOST_TEST_EQ( (x.*D2::pointer)(), 2 );
|
||||
BOOST_TEST_CSTR_EQ( D2::name, "f" );
|
||||
BOOST_TEST_EQ( D2::modifiers, mod_public | mod_function );
|
||||
}
|
||||
|
||||
{
|
||||
using L = describe_members<X, mod_any_access | mod_static | mod_function>;
|
||||
|
||||
BOOST_TEST_EQ( mp_size<L>::value, 2 );
|
||||
|
||||
using D1 = mp_at_c<L, 0>;
|
||||
|
||||
using D1 = mp_at_c<L, 0>;
|
||||
using D2 = mp_at_c<L, 1>;
|
||||
|
||||
BOOST_TEST_EQ( (*D1::pointer)( 3 ), 3 );
|
||||
BOOST_TEST_CSTR_EQ( D1::name, "f" );
|
||||
BOOST_TEST_EQ( D1::modifiers, mod_public | mod_static | mod_function );
|
||||
|
||||
BOOST_TEST_EQ( (*D2::pointer)( 4, 5 ), 9 );
|
||||
BOOST_TEST_CSTR_EQ( D2::name, "f" );
|
||||
BOOST_TEST_EQ( D2::modifiers, mod_public | mod_static | mod_function );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
#endif // !defined(BOOST_DESCRIBE_CXX14)
|
||||
74
test/overloaded_test2.cpp
Normal file
74
test/overloaded_test2.cpp
Normal file
@@ -0,0 +1,74 @@
|
||||
// Copyright 2020 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 <utility>
|
||||
|
||||
class X
|
||||
{
|
||||
private:
|
||||
|
||||
std::pair<int, int> p_;
|
||||
|
||||
public:
|
||||
|
||||
std::pair<int, int>& f() { return p_; }
|
||||
std::pair<int, int> const& f() const { return p_; }
|
||||
|
||||
BOOST_DESCRIBE_CLASS(X, (), ((std::pair<int, int>& ()) f, (std::pair<int, int> const& () const) f), (), (p_))
|
||||
};
|
||||
|
||||
|
||||
#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
|
||||
|
||||
#include <boost/mp11.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost::describe;
|
||||
using namespace boost::mp11;
|
||||
|
||||
{
|
||||
using L1 = describe_members<X, mod_any_access>;
|
||||
|
||||
BOOST_TEST_EQ( mp_size<L1>::value, 1 );
|
||||
|
||||
using D1 = mp_at_c<L1, 0>;
|
||||
|
||||
BOOST_TEST_CSTR_EQ( D1::name, "p_" );
|
||||
BOOST_TEST_EQ( D1::modifiers, mod_private );
|
||||
|
||||
X x;
|
||||
|
||||
auto& p = x.*D1::pointer;
|
||||
|
||||
using L2 = describe_members<X, mod_any_access | mod_function>;
|
||||
|
||||
BOOST_TEST_EQ( mp_size<L2>::value, 2 );
|
||||
|
||||
using D2 = mp_at_c<L2, 0>;
|
||||
using D3 = mp_at_c<L2, 1>;
|
||||
|
||||
BOOST_TEST_EQ( &(x.*D2::pointer)(), &p );
|
||||
BOOST_TEST_CSTR_EQ( D2::name, "f" );
|
||||
BOOST_TEST_EQ( D2::modifiers, mod_public | mod_function );
|
||||
|
||||
BOOST_TEST_EQ( &(x.*D3::pointer)(), &p );
|
||||
BOOST_TEST_CSTR_EQ( D3::name, "f" );
|
||||
BOOST_TEST_EQ( D3::modifiers, mod_public | mod_function );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
#endif // !defined(BOOST_DESCRIBE_CXX14)
|
||||
33
test/pp_name_test.cpp
Normal file
33
test/pp_name_test.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
// 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/pp_utilities.hpp>
|
||||
#include <boost/describe/detail/config.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
#if !defined(BOOST_DESCRIBE_CXX11)
|
||||
|
||||
#include <boost/config/pragma_message.hpp>
|
||||
|
||||
BOOST_PRAGMA_MESSAGE("Skipping test because C++11 is not available")
|
||||
int main() {}
|
||||
|
||||
#else
|
||||
|
||||
char const * s1 = BOOST_DESCRIBE_PP_NAME(x);
|
||||
char const * s2 = BOOST_DESCRIBE_PP_NAME(() y);
|
||||
char const * s3 = BOOST_DESCRIBE_PP_NAME((a) z);
|
||||
char const * s4 = BOOST_DESCRIBE_PP_NAME((a, b) w);
|
||||
|
||||
int main()
|
||||
{
|
||||
BOOST_TEST_CSTR_EQ( s1, "x" );
|
||||
BOOST_TEST_CSTR_EQ( s2, "y" );
|
||||
BOOST_TEST_CSTR_EQ( s3, "z" );
|
||||
BOOST_TEST_CSTR_EQ( s4, "w" );
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
#endif // !defined(BOOST_DESCRIBE_CXX11)
|
||||
37
test/pp_parse_test.cpp
Normal file
37
test/pp_parse_test.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
// 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/pp_utilities.hpp>
|
||||
#include <boost/describe/detail/config.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
#if !defined(BOOST_DESCRIBE_CXX11)
|
||||
|
||||
#include <boost/config/pragma_message.hpp>
|
||||
|
||||
BOOST_PRAGMA_MESSAGE("Skipping test because C++11 is not available")
|
||||
int main() {}
|
||||
|
||||
#else
|
||||
|
||||
#define S(x) S2(x)
|
||||
#define S2(x) S3(x)
|
||||
#define S3(x) #x
|
||||
|
||||
char const * s1 = S((BOOST_DESCRIBE_PP_PARSE(x)));
|
||||
char const * s2 = S((BOOST_DESCRIBE_PP_PARSE(() y)));
|
||||
char const * s3 = S((BOOST_DESCRIBE_PP_PARSE((a) z)));
|
||||
char const * s4 = S((BOOST_DESCRIBE_PP_PARSE((a, b) w)));
|
||||
|
||||
int main()
|
||||
{
|
||||
BOOST_TEST_CSTR_EQ( s1, "(0, ~, x)" );
|
||||
BOOST_TEST_CSTR_EQ( s2, "(1, (), y)" );
|
||||
BOOST_TEST_CSTR_EQ( s3, "(1, (a), z)" );
|
||||
BOOST_TEST_CSTR_EQ( s4, "(1, (a, b), w)" );
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
#endif // !defined(BOOST_DESCRIBE_CXX11)
|
||||
40
test/pp_pointer_test.cpp
Normal file
40
test/pp_pointer_test.cpp
Normal file
@@ -0,0 +1,40 @@
|
||||
// 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/pp_utilities.hpp>
|
||||
#include <boost/describe/detail/config.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
#if !defined(BOOST_DESCRIBE_CXX11)
|
||||
|
||||
#include <boost/config/pragma_message.hpp>
|
||||
|
||||
BOOST_PRAGMA_MESSAGE("Skipping test because C++11 is not available")
|
||||
int main() {}
|
||||
|
||||
#else
|
||||
|
||||
#define S(x) S2(x)
|
||||
#define S2(x) S3(x)
|
||||
#define S3(x) S4(x)
|
||||
#define S4(x) #x
|
||||
|
||||
char const * s1 = S(BOOST_DESCRIBE_PP_POINTER(C1, x));
|
||||
char const * s2 = S((BOOST_DESCRIBE_PP_POINTER(C2, (R ()) y)));
|
||||
char const * s3 = S((BOOST_DESCRIBE_PP_POINTER(C3, (R () const) z)));
|
||||
char const * s4 = S((BOOST_DESCRIBE_PP_POINTER(C4, (R (A1)) v)));
|
||||
char const * s5 = S((BOOST_DESCRIBE_PP_POINTER(C5, (R (A1, A2) const &&) w)));
|
||||
|
||||
int main()
|
||||
{
|
||||
BOOST_TEST_CSTR_EQ( s1, "&C1::x" );
|
||||
BOOST_TEST_CSTR_EQ( s2, "(::boost::describe::detail::mfn<C2, R ()>(&C2::y))" );
|
||||
BOOST_TEST_CSTR_EQ( s3, "(::boost::describe::detail::mfn<C3, R () const>(&C3::z))" );
|
||||
BOOST_TEST_CSTR_EQ( s4, "(::boost::describe::detail::mfn<C4, R (A1)>(&C4::v))" );
|
||||
BOOST_TEST_CSTR_EQ( s5, "(::boost::describe::detail::mfn<C5, R (A1, A2) const &&>(&C5::w))" );
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
#endif // !defined(BOOST_DESCRIBE_CXX11)
|
||||
16
test/struct_enum_fail.cpp
Normal file
16
test/struct_enum_fail.cpp
Normal file
@@ -0,0 +1,16 @@
|
||||
// Copyright 2021 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/describe/enum.hpp>
|
||||
|
||||
#if !defined(BOOST_DESCRIBE_CXX14)
|
||||
|
||||
#error "Skipping test because C++14 is not available"
|
||||
|
||||
#else
|
||||
|
||||
struct X {};
|
||||
BOOST_DESCRIBE_ENUM(X)
|
||||
|
||||
#endif // !defined(BOOST_DESCRIBE_CXX14)
|
||||
Reference in New Issue
Block a user