Browse Source

update: add unnamed-namespace wrapper

legacy
Dnomd343 6 months ago
parent
commit
cc85dad16a
  1. 4
      src/core_test/cases/cases_helper.h
  2. 4
      src/core_test/codec/short_code.cc
  3. 4
      src/core_test/ffi/all_cases.cc
  4. 90
      src/core_test/utility/exposer.h

4
src/core_test/cases/cases_helper.h

@ -31,8 +31,8 @@ protected:
}; };
/// Forcibly modify private variables to reset state. /// Forcibly modify private variables to reset state.
FORCE_ACCESS_VAR(AllCases, bool, available_) EXPOSE_VAR(AllCases, bool, available_)
FORCE_ACCESS_VAR(BasicRanges, bool, available_) EXPOSE_VAR(BasicRanges, bool, available_)
/// Test fixture macro with custom test suite name. /// Test fixture macro with custom test suite name.
#define TEST_FF(test_suite_name, test_name) \ #define TEST_FF(test_suite_name, test_name) \

4
src/core_test/codec/short_code.cc

@ -21,8 +21,8 @@ using klotski::codec::SHORT_CODE_LIMIT;
static const auto TEST_THREAD_NUM = 256; static const auto TEST_THREAD_NUM = 256;
/// Forcibly modify private variables to reset state. /// Forcibly modify private variables to reset state.
FORCE_ACCESS_VAR(AllCases, bool, available_) EXPOSE_VAR(AllCases, bool, available_)
FORCE_ACCESS_VAR(BasicRanges, bool, available_) EXPOSE_VAR(BasicRanges, bool, available_)
/// Reset basic ranges build state, note it is thread-unsafe. /// Reset basic ranges build state, note it is thread-unsafe.
void basic_ranges_reset() { void basic_ranges_reset() {

4
src/core_test/ffi/all_cases.cc

@ -16,8 +16,8 @@ using klotski::cases::ALL_CASES_NUM;
static constexpr std::string_view ALL_CASES_MD5 = "3888e9fab8d3cbb50908b12b147cfb23"; static constexpr std::string_view ALL_CASES_MD5 = "3888e9fab8d3cbb50908b12b147cfb23";
/// Forcibly modify private variables to reset state. /// Forcibly modify private variables to reset state.
FORCE_ACCESS_VAR(AllCases, bool, available_) EXPOSE_VAR(AllCases, bool, available_)
FORCE_ACCESS_VAR(BasicRanges, bool, available_) EXPOSE_VAR(BasicRanges, bool, available_)
/// Reset basic ranges build state, note it is thread-unsafe. /// Reset basic ranges build state, note it is thread-unsafe.
void basic_ranges_reset() { void basic_ranges_reset() {

90
src/core_test/utility/exposer.h

@ -1,13 +1,36 @@
#pragma once #pragma once
/// The exposer can forcibly access private members of a class without changing /// The Exposer can forcibly access private members of a class without changing
/// any code. It uses macros to construct a function that returns a reference /// any code, and in most scenarios, it has zero over-cost. This exposer using
/// to the target member variable. /// macros to construct function that return a reference of target variable or
/// calling target member function.
/// It supports member variables, member functions and their const versions, as
/// well as static variables and functions. They are provided via the `EXPOSE_`
/// macro, A few examples are as follows.
/// + EXPOSE_VAR(Demo, int, val)
/// + EXPOSE_CONST_VAR(Demo, int, cval)
///
/// + EXPOSE_FUNC(Demo, int(const std::string &), func)
/// + EXPOSE_CONST_FUNC(Demo, int(const std::string &), cfunc)
///
/// + EXPOSE_STATIC_VAR(Demo, int, sval)
/// + EXPOSE_STATIC_VAR(Demo, const int, scval)
///
/// + EXPOSE_STATIC_FUNC(Demo, int(std::string_view), sfunc)
/// The advantage of Exposer is that it can directly access the private members
/// without changing any content or compilation parameters. However, this is a
/// hack solution and should not be used in formal code, but only in test code.
/// Another simpler but less compatible way is to add the `-fno-access-control`
/// compilation parameter.
#include <type_traits> #include <type_traits>
// ----------------------------------------------------------------------------------------- // // ----------------------------------------------------------------------------------------- //
namespace {
namespace exposer { namespace exposer {
template <typename T, T Val, typename Dummy> template <typename T, T Val, typename Dummy>
@ -16,6 +39,7 @@ struct Exposer {
}; };
} // namespace exposer } // namespace exposer
} // namespace
// ----------------------------------------------------------------------------------------- // // ----------------------------------------------------------------------------------------- //
@ -25,27 +49,38 @@ struct Exposer {
#define UNIQUE_TAG UNIQUE_TAG_IMPL(__COUNTER__) #define UNIQUE_TAG UNIQUE_TAG_IMPL(__COUNTER__)
#define NS_EXPOSER_START \
namespace { \
namespace exposer { \
#define NS_EXPOSER_END }}
// ----------------------------------------------------------------------------------------- // // ----------------------------------------------------------------------------------------- //
#define ACCESS_SVAR_IMPL(Class, Type, Member, Dummy) \ #define ACCESS_SVAR_IMPL(Class, Type, Member, Dummy) \
NS_EXPOSER_START \
struct Dummy {}; \ struct Dummy {}; \
template struct Exposer<Type(*), &Class::Member, Dummy>; \ template struct Exposer<Type(*), &Class::Member, Dummy>; \
constexpr Type* fetch(Dummy); \ constexpr Type* fetch(Dummy); \
constexpr Type& Class##_##Member() { \ constexpr Type& Class##_##Member() { \
return *fetch(Dummy{}); \ return *fetch(Dummy{}); \
} } \
NS_EXPOSER_END
#define ACCESS_SFUNC_IMPL(Class, Proto, Member, Dummy, FuncTag) \ #define ACCESS_SFUNC_IMPL(Class, Proto, Member, Dummy, FuncTag) \
NS_EXPOSER_START \
struct Dummy {}; \ struct Dummy {}; \
using FuncTag = Proto; \ using FuncTag = Proto; \
template struct Exposer<FuncTag(*), &Class::Member, Dummy>; \ template struct Exposer<FuncTag(*), &Class::Member, Dummy>; \
constexpr FuncTag* fetch(Dummy); \ constexpr FuncTag* fetch(Dummy); \
template<typename ...Args> \ template <typename ...Args> \
constexpr decltype(auto) sfunc(Args &&...args) { \ constexpr decltype(auto) sfunc(Args &&...args) { \
return fetch(Dummy{})(std::forward<Args>(args)...); \ return fetch(Dummy{})(std::forward<Args>(args)...); \
} } \
NS_EXPOSER_END
#define ACCESS_VAR_IMPL(Class, Type, ConstType, Member, Dummy) \ #define ACCESS_VAR_IMPL(Class, Type, ConstType, Member, Dummy) \
NS_EXPOSER_START \
struct Dummy {}; \ struct Dummy {}; \
template struct Exposer<Type(Class::*), &Class::Member, Dummy>; \ template struct Exposer<Type(Class::*), &Class::Member, Dummy>; \
constexpr Type Class::* fetch(Dummy); \ constexpr Type Class::* fetch(Dummy); \
@ -57,9 +92,11 @@ struct Exposer {
} \ } \
constexpr ConstType& Class##_##Member(const Class &c) { \ constexpr ConstType& Class##_##Member(const Class &c) { \
return c.*fetch(Dummy{}); \ return c.*fetch(Dummy{}); \
} } \
NS_EXPOSER_END
#define ACCESS_FUNC_IMPL(Class, Proto, Member, Dummy, FuncTag) \ #define ACCESS_FUNC_IMPL(Class, Proto, Member, Dummy, FuncTag) \
NS_EXPOSER_START \
struct Dummy {}; \ struct Dummy {}; \
using FuncTag = Proto; \ using FuncTag = Proto; \
template struct Exposer<FuncTag(Class::*), &Class::Member, Dummy>; \ template struct Exposer<FuncTag(Class::*), &Class::Member, Dummy>; \
@ -68,42 +105,31 @@ struct Exposer {
requires std::is_same_v<std::decay_t<C>, Class> \ requires std::is_same_v<std::decay_t<C>, Class> \
constexpr decltype(auto) Class##_##Member(C &&c, Args &&...args) { \ constexpr decltype(auto) Class##_##Member(C &&c, Args &&...args) { \
return (std::forward<C>(c).*fetch(Dummy{}))(std::forward<Args>(args)...); \ return (std::forward<C>(c).*fetch(Dummy{}))(std::forward<Args>(args)...); \
} } \
NS_EXPOSER_END
// ----------------------------------------------------------------------------------------- // // ----------------------------------------------------------------------------------------- //
#define EXPOSE_STATIC_VAR(Class, Type, Member) \ #define EXPOSE_STATIC_VAR(Class, Type, Member) \
namespace exposer { \ ACCESS_SVAR_IMPL(Class, Type, Member, UNIQUE_TAG)
ACCESS_SVAR_IMPL(Class, Type, Member, UNIQUE_TAG) \
}
#define EXPOSE_STATIC_FUNC(Class, Proto, Member) \ #define EXPOSE_STATIC_FUNC(Class, Proto, Member) \
namespace exposer { \ ACCESS_SFUNC_IMPL(Class, Proto, Member, UNIQUE_TAG, UNIQUE_TAG)
ACCESS_SFUNC_IMPL(Class, Proto, Member, UNIQUE_TAG, UNIQUE_TAG) \
}
// ----------------------------------------------------------------------------------------- // // ----------------------------------------------------------------------------------------- //
#define EXPOSE_VAR(Class, Type, Member) \ #define EXPOSE_VAR(Class, Type, Member) \
namespace exposer { \ ACCESS_VAR_IMPL(Class, Type, const Type, Member, UNIQUE_TAG)
ACCESS_VAR_IMPL(Class, Type, const Type, Member, UNIQUE_TAG) \
}
#define EXPOSE_FUNC(Class, Proto, Member) \ #define EXPOSE_FUNC(Class, Proto, Member) \
namespace exposer { \ ACCESS_FUNC_IMPL(Class, Proto, Member, UNIQUE_TAG, UNIQUE_TAG)
ACCESS_FUNC_IMPL(Class, Proto, Member, UNIQUE_TAG, UNIQUE_TAG) \
}
// ----------------------------------------------------------------------------------------- // // ----------------------------------------------------------------------------------------- //
#define EXPOSE_CONST_VAR(Class, Type, Member) \ #define EXPOSE_CONST_VAR(Class, Type, Member) \
namespace exposer { \ ACCESS_VAR_IMPL(Class, const Type, const Type, Member, UNIQUE_TAG)
ACCESS_VAR_IMPL(Class, const Type, const Type, Member, UNIQUE_TAG) \
}
#define EXPOSE_CONST_FUNC(Class, Proto, Member) \ #define EXPOSE_CONST_FUNC(Class, Proto, Member) \
namespace exposer { \ ACCESS_FUNC_IMPL(Class, Proto const, Member, UNIQUE_TAG, UNIQUE_TAG)
ACCESS_FUNC_IMPL(Class, Proto const, Member, UNIQUE_TAG, UNIQUE_TAG) \
}
// ----------------------------------------------------------------------------------------- // // ----------------------------------------------------------------------------------------- //

Loading…
Cancel
Save