diff --git a/src/core_test/cases/cases_helper.h b/src/core_test/cases/cases_helper.h index a525c8c..d50ee78 100644 --- a/src/core_test/cases/cases_helper.h +++ b/src/core_test/cases/cases_helper.h @@ -31,8 +31,8 @@ protected: }; /// Forcibly modify private variables to reset state. -FORCIBLY_ACCESS(AllCases, available_, bool) -FORCIBLY_ACCESS(BasicRanges, available_, bool) +FORCE_ACCESS_VAR(AllCases, bool, available_) +FORCE_ACCESS_VAR(BasicRanges, bool, available_) /// Test fixture macro with custom test suite name. #define TEST_FF(test_suite_name, test_name) \ diff --git a/src/core_test/codec/short_code.cc b/src/core_test/codec/short_code.cc index 03e648d..fd2f1a6 100644 --- a/src/core_test/codec/short_code.cc +++ b/src/core_test/codec/short_code.cc @@ -21,17 +21,17 @@ using klotski::codec::SHORT_CODE_LIMIT; static const auto TEST_THREAD_NUM = 256; /// Forcibly modify private variables to reset state. -//FORCIBLY_ACCESS(AllCases, available_, bool) -//FORCIBLY_ACCESS(BasicRanges, available_, bool) +FORCE_ACCESS_VAR(AllCases, bool, available_) +FORCE_ACCESS_VAR(BasicRanges, bool, available_) /// Reset basic ranges build state, note it is thread-unsafe. void basic_ranges_reset() { -// exposer::BasicRanges_available_(BasicRanges::instance()) = false; + exposer::BasicRanges_available_(BasicRanges::instance()) = false; } /// Reset all cases build state, note it is thread-unsafe. void all_cases_reset() { -// exposer::AllCases_available_(AllCases::instance()) = false; + exposer::AllCases_available_(AllCases::instance()) = false; } TEST(ShortCode, limit) { diff --git a/src/core_test/ffi/all_cases.cc b/src/core_test/ffi/all_cases.cc index 81b5a3d..30921b1 100644 --- a/src/core_test/ffi/all_cases.cc +++ b/src/core_test/ffi/all_cases.cc @@ -16,37 +16,17 @@ using klotski::cases::ALL_CASES_NUM; static constexpr std::string_view ALL_CASES_MD5 = "3888e9fab8d3cbb50908b12b147cfb23"; /// Forcibly modify private variables to reset state. -//FORCIBLY_ACCESS(AllCases, available_, bool) -//FORCIBLY_ACCESS(BasicRanges, available_, bool) - -FORCE_ACCESS_VAR(BasicRanges, available_, bool, Helper_1); -FORCE_ACCESS_VAR(AllCases, available_, bool, Helper_2); - -//namespace exposer { -// -//struct Helper_1 {}; -// -//template struct Exposer; -// -////template<> -//constexpr bool BasicRanges::* fetch(Helper_1); -// -//bool& Demo_val(BasicRanges &c) { -// return c.*fetch(Helper_1{}); -//} -// -//} +FORCE_ACCESS_VAR(AllCases, bool, available_) +FORCE_ACCESS_VAR(BasicRanges, bool, available_) /// Reset basic ranges build state, note it is thread-unsafe. void basic_ranges_reset() { exposer::BasicRanges_available_(BasicRanges::instance()) = false; -// exposer::BasicRanges_available_(BasicRanges::instance()) = false; } /// Reset all cases build state, note it is thread-unsafe. void all_cases_reset() { exposer::AllCases_available_(AllCases::instance()) = false; -// exposer::AllCases_available_(AllCases::instance()) = false; } TEST(AllCases, all_cases_prebuild) { diff --git a/src/core_test/utility/exposer.h b/src/core_test/utility/exposer.h index 0923269..f959df2 100644 --- a/src/core_test/utility/exposer.h +++ b/src/core_test/utility/exposer.h @@ -6,52 +6,34 @@ namespace exposer { -// REF: http://bloglitb.blogspot.com/2010/07/access-to-private-members-thats-easy.html - -//template -//struct Exposer { -// static T ptr; -//}; -// -//template -//T Exposer::ptr; -// -//template -//struct ExposerImpl { -// static struct Factory { -// Factory() { Exposer::ptr = Ptr; } -// } factory; -//}; -// -//template -//typename ExposerImpl::Factory ExposerImpl::factory; - -//template -//constexpr T fetch(); - -//template -template +template struct Exposer { -// constexpr friend T fetch<>() { return Val; } - constexpr friend T fetch(Unique) { return Val; } + constexpr friend T fetch(Tag) { return Val; } }; } // namespace exposer -#define FORCIBLY_ACCESS(Class, Member, Type) \ - namespace exposer { \ - template struct ExposerImpl; \ - inline auto& Class##_##Member(Class &T) { \ - return T.*exposer::Exposer::ptr; \ - } \ - } +#define COMBINE_IMPL(x, y) x##y + +#define COMBINE(x, y) COMBINE_IMPL(x, y) + +#define UNIQUE_TAG COMBINE(Tag, __COUNTER__) -#define FORCE_ACCESS_VAR(Class, Member, Type, Unique) \ +#define FORCE_ACCESS_VAR_IMPL(Class, Type, Member, Tag) \ namespace exposer { \ - struct Unique {}; \ - template struct Exposer; \ - constexpr Type Class::* fetch(Unique); \ - Type& Class##_##Member(Class &T) { \ - return T.*fetch(Unique{}); \ + struct Tag {}; \ + template struct Exposer; \ + constexpr Type Class::* fetch(Tag); \ + constexpr Type& Class##_##Member(Class &c) { \ + return c.*fetch(Tag{}); \ + } \ + constexpr const Type& Class##_##Member(const Class &c) { \ + return c.*fetch(Tag{}); \ + } \ + constexpr Type Class##_##Member(Class &&c) { \ + return c.*fetch(Tag{}); \ } \ } + +#define FORCE_ACCESS_VAR(Class, Type, Member) \ + FORCE_ACCESS_VAR_IMPL(Class, Type, Member, UNIQUE_TAG)