Remove fmt dependency. Add PublicCast
This commit is contained in:
parent
b325c54968
commit
6fa97fcb87
5 changed files with 134 additions and 11 deletions
|
@ -12,6 +12,8 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
set(BOOST_INCLUDE_LIBRARIES "pfr")
|
||||
set(NAMEOF_OPT_INSTALL ON)
|
||||
|
||||
|
||||
option(CPM_USE_LOCAL_PACKAGES "Use local packages" ON)
|
||||
option(UTEMPL_MODULE OFF)
|
||||
|
@ -49,22 +51,24 @@ set(TMP ${CPM_USE_LOCAL_PACKAGES})
|
|||
set(CPM_USE_LOCAL_PACKAGES OFF)
|
||||
|
||||
CPMAddPackage(
|
||||
NAME fmt
|
||||
NAME nameof
|
||||
URL
|
||||
"https://github.com/fmtlib/fmt/releases/download/11.0.2/fmt-11.0.2.zip"
|
||||
"https://helicopter.myftp.org/git/sha512sum/nameof_module/archive/master.tar.gz"
|
||||
EXCLUDE_FROM_ALL ON
|
||||
OPTIONS "FMT_MODULE ON"
|
||||
OPTIONS "NAMEOF_MODULE ON"
|
||||
)
|
||||
|
||||
set(CPM_USE_LOCAL_PACKAGES ${TMP})
|
||||
|
||||
else()
|
||||
|
||||
CPMAddPackage("gh:fmtlib/fmt#11.0.2")
|
||||
CPMAddPackage("gh:Neargye/nameof@0.10.4")
|
||||
|
||||
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
cmake_policy(SET CMP0079 NEW)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
@ -106,11 +110,11 @@ if(UTEMPL_MODULE)
|
|||
endif()
|
||||
endforeach()
|
||||
if(TARGET Boost::pfr)
|
||||
target_link_libraries(utempl PUBLIC fmt::fmt
|
||||
target_link_libraries(utempl PUBLIC nameof::nameof
|
||||
Boost::pfr)
|
||||
else()
|
||||
find_package(Boost 1.85.0 REQUIRED)
|
||||
target_link_libraries(utempl PUBLIC fmt::fmt
|
||||
target_link_libraries(utempl PUBLIC nameof::nameof
|
||||
${Boost_LIBRARIES})
|
||||
endif()
|
||||
target_include_directories(utempl PUBLIC
|
||||
|
@ -146,12 +150,12 @@ else()
|
|||
endif()
|
||||
endforeach()
|
||||
if(TARGET Boost::pfr)
|
||||
target_link_libraries(utempl INTERFACE fmt::fmt
|
||||
Boost::pfr)
|
||||
target_link_libraries(utempl INTERFACE nameof::nameof
|
||||
Boost::pfr nameof::nameof)
|
||||
else()
|
||||
find_package(Boost 1.85.0 REQUIRED)
|
||||
target_link_libraries(utempl INTERFACE fmt::fmt
|
||||
${Boost_LIBRARIES})
|
||||
target_link_libraries(utempl INTERFACE nameof::nameof
|
||||
${Boost_LIBRARIES} nameof::nameof)
|
||||
endif()
|
||||
target_include_directories(utempl INTERFACE
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/_headers>
|
||||
|
|
38
examples/src/public_cast.cpp
Normal file
38
examples/src/public_cast.cpp
Normal file
|
@ -0,0 +1,38 @@
|
|||
#include <utempl/utempl.hpp>
|
||||
|
||||
using namespace utempl; // NOLINT
|
||||
|
||||
struct A {
|
||||
private:
|
||||
[[nodiscard]] constexpr auto Method() const -> int {
|
||||
return 1;
|
||||
};
|
||||
[[nodiscard]] constexpr auto Method(int) const -> int {
|
||||
return 2;
|
||||
};
|
||||
[[nodiscard]] constexpr auto Method() -> int {
|
||||
return 3;
|
||||
};
|
||||
};
|
||||
|
||||
namespace utempl {
|
||||
|
||||
template struct PublicCast<static_cast<int (A::*)() const>(&A::Method)>;
|
||||
|
||||
template struct PublicCast<static_cast<int (A::*)(int) const>(&A::Method)>;
|
||||
|
||||
template struct PublicCast<static_cast<int (A::*)()>(&A::Method)>;
|
||||
|
||||
} // namespace utempl
|
||||
|
||||
constexpr A a;
|
||||
|
||||
static_assert(GetPrivateMemberOverloaded<"Method">(a) == 1);
|
||||
static_assert(GetPrivateMemberOverloaded<"Method">(a, 1) == 2);
|
||||
static_assert(GetPrivateMemberOverloaded<"Method">(A{}) == 3);
|
||||
|
||||
static_assert((a.*GetPrivateMember<"Method", 0, A>())() == 1);
|
||||
|
||||
static_assert((a.*GetPrivateMember<"Method", 1>(a))(1) == 2);
|
||||
|
||||
auto main() -> int {};
|
80
src/public_cast.cpp
Normal file
80
src/public_cast.cpp
Normal file
|
@ -0,0 +1,80 @@
|
|||
#pragma once
|
||||
|
||||
#include <utempl/module.hpp>
|
||||
|
||||
#ifdef UTEMPL_MODULE
|
||||
|
||||
export module utempl.public_cast;
|
||||
import utempl.loopholes;
|
||||
import std;
|
||||
import utempl.overloaded;
|
||||
import utempl.string;
|
||||
import nameof;
|
||||
|
||||
#else
|
||||
#include <nameof.hpp>
|
||||
#include <utempl/loopholes/counter.hpp>
|
||||
#include <utempl/overloaded.hpp>
|
||||
#endif
|
||||
|
||||
namespace utempl {
|
||||
|
||||
namespace impl { // For headers
|
||||
|
||||
template <typename T, ConstexprString Str>
|
||||
struct PublicCast {
|
||||
template <std::size_t I>
|
||||
struct Tag {};
|
||||
};
|
||||
|
||||
template <typename Ptr>
|
||||
using MainT = decltype(Overloaded([]<typename T, typename R, typename... Args>(R (T::*ptr)(Args...)) -> T {},
|
||||
[]<typename T, typename R, typename... Args>(R (T::*ptr)(Args...) const) -> T {},
|
||||
[]<typename T, typename R>(R T::* ptr) -> T {})(std::declval<Ptr>()));
|
||||
|
||||
template <auto ptr>
|
||||
constexpr auto TransformPtr() {
|
||||
return utempl::Overloaded(
|
||||
[]<typename T, typename R, typename... Args>(R (T::*)(Args...)) {
|
||||
return [](T* obj, Args... args) -> R {
|
||||
return (obj->*ptr)(std::forward<Args>(args)...);
|
||||
};
|
||||
},
|
||||
[]<typename T, typename R, typename... Args>(R (T::*)(Args...) const) {
|
||||
return [](const T* obj, Args... args) -> R {
|
||||
return (obj->*ptr)(std::forward<Args>(args)...);
|
||||
};
|
||||
})(ptr);
|
||||
};
|
||||
|
||||
} // namespace impl
|
||||
|
||||
UTEMPL_EXPORT template <auto Ptr,
|
||||
auto F = [] {},
|
||||
typename T = impl::MainT<decltype(Ptr)>,
|
||||
ConstexprString Str =
|
||||
utempl::ConstexprString<nameof::nameof_member<Ptr>().size() + 1>{nameof::nameof_member<Ptr>()},
|
||||
typename Tag = impl::PublicCast<T, Str>,
|
||||
auto I = loopholes::Counter<Tag, decltype(F)>(),
|
||||
auto = loopholes::Injector<typename Tag::template Tag<I>{}, Ptr>{}>
|
||||
struct PublicCast {};
|
||||
|
||||
UTEMPL_EXPORT template <ConstexprString Name, std::size_t I = 0, typename T>
|
||||
constexpr auto GetPrivateMember() -> decltype(Magic(loopholes::Getter<typename impl::PublicCast<T, Name>::template Tag<I>{}>{})) {
|
||||
return Magic(loopholes::Getter<typename impl::PublicCast<T, Name>::template Tag<I>{}>{});
|
||||
}
|
||||
|
||||
UTEMPL_EXPORT template <ConstexprString Name, std::size_t I = 0, typename T>
|
||||
constexpr auto GetPrivateMember(const T&) -> decltype(GetPrivateMember<Name, I, std::decay_t<T>>()) {
|
||||
return GetPrivateMember<Name, I, std::decay_t<T>>();
|
||||
}
|
||||
|
||||
UTEMPL_EXPORT template <utempl::ConstexprString Name, typename T, auto F = [] {}, typename... Args>
|
||||
constexpr auto GetPrivateMemberOverloaded(T&& obj, Args&&... args) -> decltype(auto) {
|
||||
return [&]<std::size_t... Is>(std::index_sequence<Is...>) -> decltype(auto) {
|
||||
return Overloaded(impl::TransformPtr<GetPrivateMember<Name, Is, std::decay_t<T>>()>()...)(std::addressof(obj),
|
||||
std::forward<Args>(args)...);
|
||||
}(std::make_index_sequence<loopholes::CountValue<impl::PublicCast<std::decay_t<T>, Name>, decltype(F)>()>());
|
||||
};
|
||||
|
||||
} // namespace utempl
|
|
@ -13,6 +13,7 @@ export import utempl.overloaded;
|
|||
export import utempl.utils;
|
||||
export import utempl.go_interface;
|
||||
export import utempl.optional;
|
||||
export import utempl.public_cast;
|
||||
|
||||
#else
|
||||
#include <utempl/attributes.hpp>
|
||||
|
@ -23,6 +24,7 @@ export import utempl.optional;
|
|||
#include <utempl/meta_info.hpp>
|
||||
#include <utempl/optional.hpp>
|
||||
#include <utempl/overloaded.hpp>
|
||||
#include <utempl/public_cast.hpp>
|
||||
#include <utempl/tuple.hpp>
|
||||
#include <utempl/type_list.hpp>
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
#ifdef UTEMPL_MODULE
|
||||
export module utempl.utils;
|
||||
import std;
|
||||
import fmt;
|
||||
import utempl.string;
|
||||
import utempl.tuple;
|
||||
import utempl.type_list;
|
||||
|
|
Loading…
Reference in a new issue