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_CXX_EXTENSIONS OFF)
|
||||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
set(BOOST_INCLUDE_LIBRARIES "pfr")
|
set(BOOST_INCLUDE_LIBRARIES "pfr")
|
||||||
|
set(NAMEOF_OPT_INSTALL ON)
|
||||||
|
|
||||||
|
|
||||||
option(CPM_USE_LOCAL_PACKAGES "Use local packages" ON)
|
option(CPM_USE_LOCAL_PACKAGES "Use local packages" ON)
|
||||||
option(UTEMPL_MODULE OFF)
|
option(UTEMPL_MODULE OFF)
|
||||||
|
@ -49,22 +51,24 @@ set(TMP ${CPM_USE_LOCAL_PACKAGES})
|
||||||
set(CPM_USE_LOCAL_PACKAGES OFF)
|
set(CPM_USE_LOCAL_PACKAGES OFF)
|
||||||
|
|
||||||
CPMAddPackage(
|
CPMAddPackage(
|
||||||
NAME fmt
|
NAME nameof
|
||||||
URL
|
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
|
EXCLUDE_FROM_ALL ON
|
||||||
OPTIONS "FMT_MODULE ON"
|
OPTIONS "NAMEOF_MODULE ON"
|
||||||
)
|
)
|
||||||
|
|
||||||
set(CPM_USE_LOCAL_PACKAGES ${TMP})
|
set(CPM_USE_LOCAL_PACKAGES ${TMP})
|
||||||
|
|
||||||
else()
|
else()
|
||||||
|
|
||||||
CPMAddPackage("gh:fmtlib/fmt#11.0.2")
|
CPMAddPackage("gh:Neargye/nameof@0.10.4")
|
||||||
|
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
cmake_policy(SET CMP0079 NEW)
|
cmake_policy(SET CMP0079 NEW)
|
||||||
|
|
||||||
include(GNUInstallDirs)
|
include(GNUInstallDirs)
|
||||||
|
@ -106,11 +110,11 @@ if(UTEMPL_MODULE)
|
||||||
endif()
|
endif()
|
||||||
endforeach()
|
endforeach()
|
||||||
if(TARGET Boost::pfr)
|
if(TARGET Boost::pfr)
|
||||||
target_link_libraries(utempl PUBLIC fmt::fmt
|
target_link_libraries(utempl PUBLIC nameof::nameof
|
||||||
Boost::pfr)
|
Boost::pfr)
|
||||||
else()
|
else()
|
||||||
find_package(Boost 1.85.0 REQUIRED)
|
find_package(Boost 1.85.0 REQUIRED)
|
||||||
target_link_libraries(utempl PUBLIC fmt::fmt
|
target_link_libraries(utempl PUBLIC nameof::nameof
|
||||||
${Boost_LIBRARIES})
|
${Boost_LIBRARIES})
|
||||||
endif()
|
endif()
|
||||||
target_include_directories(utempl PUBLIC
|
target_include_directories(utempl PUBLIC
|
||||||
|
@ -146,12 +150,12 @@ else()
|
||||||
endif()
|
endif()
|
||||||
endforeach()
|
endforeach()
|
||||||
if(TARGET Boost::pfr)
|
if(TARGET Boost::pfr)
|
||||||
target_link_libraries(utempl INTERFACE fmt::fmt
|
target_link_libraries(utempl INTERFACE nameof::nameof
|
||||||
Boost::pfr)
|
Boost::pfr nameof::nameof)
|
||||||
else()
|
else()
|
||||||
find_package(Boost 1.85.0 REQUIRED)
|
find_package(Boost 1.85.0 REQUIRED)
|
||||||
target_link_libraries(utempl INTERFACE fmt::fmt
|
target_link_libraries(utempl INTERFACE nameof::nameof
|
||||||
${Boost_LIBRARIES})
|
${Boost_LIBRARIES} nameof::nameof)
|
||||||
endif()
|
endif()
|
||||||
target_include_directories(utempl INTERFACE
|
target_include_directories(utempl INTERFACE
|
||||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/_headers>
|
$<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.utils;
|
||||||
export import utempl.go_interface;
|
export import utempl.go_interface;
|
||||||
export import utempl.optional;
|
export import utempl.optional;
|
||||||
|
export import utempl.public_cast;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#include <utempl/attributes.hpp>
|
#include <utempl/attributes.hpp>
|
||||||
|
@ -23,6 +24,7 @@ export import utempl.optional;
|
||||||
#include <utempl/meta_info.hpp>
|
#include <utempl/meta_info.hpp>
|
||||||
#include <utempl/optional.hpp>
|
#include <utempl/optional.hpp>
|
||||||
#include <utempl/overloaded.hpp>
|
#include <utempl/overloaded.hpp>
|
||||||
|
#include <utempl/public_cast.hpp>
|
||||||
#include <utempl/tuple.hpp>
|
#include <utempl/tuple.hpp>
|
||||||
#include <utempl/type_list.hpp>
|
#include <utempl/type_list.hpp>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
#ifdef UTEMPL_MODULE
|
#ifdef UTEMPL_MODULE
|
||||||
export module utempl.utils;
|
export module utempl.utils;
|
||||||
import std;
|
import std;
|
||||||
import fmt;
|
|
||||||
import utempl.string;
|
import utempl.string;
|
||||||
import utempl.tuple;
|
import utempl.tuple;
|
||||||
import utempl.type_list;
|
import utempl.type_list;
|
||||||
|
|
Loading…
Reference in a new issue