Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions include/stdx/ct_string.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -242,5 +242,10 @@ template <std::size_t N>
// NOLINTNEXTLINE(*-avoid-c-arrays)
map_value_helper(char const (&)[N]) -> map_value_helper<ct_string<N>>;
} // namespace detail

template <ct_string S>
consteval auto shrink() -> decltype(detail::shrink<S>()) {
return {};
}
} // namespace v1
} // namespace stdx
23 changes: 23 additions & 0 deletions include/stdx/type_traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,20 +223,39 @@ template <typename T> struct shrinkwrap {
using type = T;
};

template <auto V> struct shrinkwrap_value {
using is_shrinkwrapped_value = void;
constexpr static auto value = V;
};

template <typename T>
concept is_shrinkwrapped = requires { typename T::is_shrinkwrapped; };
template <typename T>
concept is_shrinkwrapped_value =
requires { typename T::is_shrinkwrapped_value; };

template <typename T,
auto F = []()->auto (*)() -> shrinkwrap<T> { return nullptr; }>
consteval auto shrink() {
return F;
}

template <auto T,
auto F = []()->auto (*)() -> shrinkwrap_value<T> { return nullptr; }>
consteval auto shrink() {
return F;
}

template <typename T>
concept is_shrunk = requires(T const &t) {
{ t()() } -> is_shrinkwrapped;
};

template <typename T>
concept is_shrunk_value = requires(T const &t) {
{ t()() } -> is_shrinkwrapped_value;
};

template <typename T> consteval auto maybe_expand() -> T;
template <is_shrunk T>
consteval auto maybe_expand() -> typename decltype(T{}()())::type;
Expand All @@ -257,6 +276,10 @@ constexpr auto maybe_expand(T &&) ->
"object: use expand_t<T>{} instead if this is what you want");
return R{};
}
template <is_shrunk_value T> constexpr auto maybe_expand(T &&) {
using R = decltype(std::remove_cvref_t<T>{}()());
return R::value;
}
} // namespace detail

template <typename T> consteval auto shrink() -> decltype(detail::shrink<T>()) {
Expand Down
36 changes: 36 additions & 0 deletions test/type_traits.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <stdx/ct_conversions.hpp>
#include <stdx/ct_string.hpp>
#include <stdx/type_traits.hpp>

#include <catch2/catch_test_macros.hpp>
Expand Down Expand Up @@ -244,6 +245,12 @@ TEST_CASE("type shrinkage (by type)", "[type_traits]") {
STATIC_CHECK(std::is_same_v<stdx::expand_t<X>, C>);
}

TEST_CASE("two shrunk types are considered the same", "[type_traits]") {
using X = stdx::shrink_t<C>;
using Y = stdx::shrink_t<C>;
STATIC_CHECK(std::is_same_v<X, Y>);
}

TEST_CASE("type shrinkage (by value)", "[type_traits]") {
auto c = C{};
auto x = stdx::shrink(c);
Expand All @@ -253,6 +260,35 @@ TEST_CASE("type shrinkage (by value)", "[type_traits]") {
STATIC_CHECK(std::is_same_v<decltype(y), C>);
}

TEST_CASE("value shrinkage for ct_strings", "[type_traits]") {
using namespace stdx::literals;
constexpr auto x = stdx::shrink<"hello"_cts>();
constexpr auto y = stdx::expand(x);
STATIC_CHECK(y == "hello"_cts);
}

TEST_CASE("two shrunk ct_strings are considered the same type",
"[type_traits]") {
constexpr auto x = stdx::shrink<"hello">();
constexpr auto y = stdx::shrink<"hello">();
STATIC_CHECK(std::is_same_v<decltype(x), decltype(y)>);
}

namespace {
template <auto T> consteval auto return_expanded() { return stdx::expand(T); }
} // namespace

TEST_CASE("pass shrunk ct_string as template argument", "[type_traits]") {
using namespace stdx::literals;
STATIC_CHECK(return_expanded<stdx::shrink<"hello"_cts>()>() == "hello"_cts);
}

TEST_CASE("non-shrunk value can be expanded (with no effect)",
"[type_traits]") {
constexpr auto x = stdx::expand(42);
STATIC_CHECK(x == 42);
}

TEST_CASE("nth type in pack", "[type_traits]") {
STATIC_REQUIRE(
std::is_same_v<stdx::nth_t<2, bool, char, float, int>, float>);
Expand Down