Skip to content

Commit

Permalink
toying with concepts
Browse files Browse the repository at this point in the history
  • Loading branch information
k0zmo committed Oct 27, 2020
1 parent 86e54cb commit 45df321
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 44 deletions.
43 changes: 16 additions & 27 deletions include/kl/ctti.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,51 +9,40 @@
#include <string>

namespace kl {
namespace detail {

KL_VALID_EXPR_HELPER(has_reflect_struct,
reflect_struct(0, std::declval<T&>(), record<T>))

} // namespace detail
template <typename T>
concept reflectable =
requires(T&& a) {
{ reflect_struct(0, a, kl::record<std::remove_cvref_t<T>>) };
};

template <typename T>
using is_reflectable = detail::has_reflect_struct<T>;
using is_reflectable = std::bool_constant<reflectable<T>>;

template <typename T>
inline constexpr bool is_reflectable_v = is_reflectable<T>::value;

struct ctti
{
template <typename T>
static constexpr bool is_reflectable = kl::is_reflectable_v<T>;

template <typename Reflected>
template <typename R>
static std::string name()
{
return boost::typeindex::type_id<Reflected>().pretty_name();
return boost::typeindex::type_id<R>().pretty_name();
}

template <typename Reflected, typename Visitor>
static constexpr void reflect(Reflected&& r, Visitor&& v)
template <reflectable R, typename Visitor>
static constexpr void reflect(R&& r, Visitor&& v)
{
using R = remove_cvref_t<Reflected>;

static_assert(
detail::has_reflect_struct_v<R>,
"Can't reflect this type. Define reflect_struct function");
reflect_struct(std::forward<Visitor>(v), std::forward<Reflected>(r),
record<R>);
using PlainR = std::remove_cvref_t<R>;
reflect_struct(std::forward<Visitor>(v), std::forward<R>(r),
record<PlainR>);
}

template <typename Reflected>
template <reflectable R>
static constexpr std::size_t num_fields() noexcept
{
using R = remove_cvref_t<Reflected>;

static_assert(
detail::has_reflect_struct_v<R>,
"Can't reflect this type. Define reflect_struct function");
return reflect_num_fields(record<R>);
using PlainR = std::remove_cvref_t<R>;
return reflect_num_fields(record<PlainR>);
}
};
} // namespace kl
10 changes: 0 additions & 10 deletions include/kl/type_traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,16 +94,6 @@ template <typename T, typename U>
struct is_same<T, U> : std::integral_constant<bool, std::is_same_v<T, U>>
{
};

// C++20 stuff
template <typename T>
struct remove_cvref
{
using type = std::remove_cv_t<std::remove_reference_t<T>>;
};

template <typename T>
using remove_cvref_t = typename remove_cvref<T>::type;
} // namespace kl

#define KL_HAS_TYPEDEF_HELPER(type) \
Expand Down
2 changes: 1 addition & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
add_library(kl_cxx_flags INTERFACE)
target_compile_features(kl_cxx_flags INTERFACE cxx_std_17)
target_compile_features(kl_cxx_flags INTERFACE cxx_std_20)

if(KL_DEV_BUILD)
include(DevFlags)
Expand Down
12 changes: 6 additions & 6 deletions tests/ctti_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,12 +123,12 @@ TEST_CASE("ctti")
SECTION("type not registered")
{
using T = std::vector<int>;
REQUIRE(!kl::ctti::is_reflectable<T>);
REQUIRE(!kl::is_reflectable_v<T>);
}

SECTION("global type A")
{
REQUIRE(kl::ctti::is_reflectable<A>);
REQUIRE(kl::is_reflectable_v<A>);
REQUIRE(kl::ctti::num_fields<A>() == 2);

std::ostringstream ss;
Expand All @@ -144,7 +144,7 @@ TEST_CASE("ctti")
{
using B = ns::B;

REQUIRE(kl::ctti::is_reflectable<B>);
REQUIRE(kl::is_reflectable_v<B>);
REQUIRE(kl::ctti::num_fields<B>() == 3);

std::ostringstream ss;
Expand Down Expand Up @@ -181,7 +181,7 @@ TEST_CASE("ctti")

SECTION("type S in namespace ns with std::array<>")
{
REQUIRE(kl::ctti::is_reflectable<S>);
REQUIRE(kl::reflectable<S>);
static_assert(kl::ctti::num_fields<S>() == 4);

const S s = {5, false, {3.14f}, A{"ZXC", {1, 2, 3, 4, 5, 6}, 0}};
Expand All @@ -198,7 +198,7 @@ TEST_CASE("ctti")

SECTION("type Sdev")
{
REQUIRE(kl::ctti::is_reflectable<Sdev>);
REQUIRE(kl::reflectable<Sdev>);
static_assert(kl::ctti::num_fields<Sdev>() == 3);

Sdev sd{};
Expand All @@ -219,7 +219,7 @@ TEST_CASE("ctti")
{
using T = ns::inner::T;

REQUIRE(kl::ctti::is_reflectable<T>);
REQUIRE(kl::reflectable<T>);
REQUIRE(kl::ctti::num_fields<T>() == 2 + 2+ 4);

T t{"HELLO",{"WORLD", "Hello"}};
Expand Down

0 comments on commit 45df321

Please sign in to comment.