Skip to content

Commit

Permalink
Merge branch 'main' of github.com:asoffer/nth into main
Browse files Browse the repository at this point in the history
  • Loading branch information
asoffer committed Dec 3, 2023
2 parents efeca85 + 0d87f06 commit ed3df86
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 21 deletions.
24 changes: 13 additions & 11 deletions nth/debug/contracts/internal/contracts.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,19 @@ inline constexpr char const EnsureLogLine[] =

#define NTH_DEBUG_INTERNAL_CONTRACT_CHECK(log_line, verbosity, responder_type, \
action_prefix, ...) \
if (::nth::debug::internal_contracts::responder_type NthInternalResponder; \
NTH_DEBUG_INTERNAL_VERBOSITY_DISABLED(verbosity) or \
[&](::nth::source_location NthInternalourceLocation) \
-> decltype(auto) { \
static ::nth::internal_debug::LogLineWithArity<3> const \
NthInternalLogLine(log_line, NthInternalourceLocation); \
NthInternalResponder.set_log_line(NthInternalLogLine); \
return (NthInternalResponder); \
}(::nth::source_location::current()) \
.set((#__VA_ARGS__), \
NTH_DEBUG_INTERNAL_TRACE_INJECTED_EXPR(__VA_ARGS__))) { \
if (NTH_DEBUG_INTERNAL_VERBOSITY_DISABLED(verbosity)) { \
} else if (::nth::debug::internal_contracts::responder_type \
NthInternalResponder; \
[&](::nth::source_location NthInternalourceLocation) \
-> decltype(auto) { \
static ::nth::internal_debug::LogLineWithArity<3> const \
NthInternalLogLine(log_line, NthInternalourceLocation); \
NthInternalResponder.set_log_line(NthInternalLogLine); \
return (NthInternalResponder); \
}(::nth::source_location::current()) \
.set((#__VA_ARGS__), \
NTH_DEBUG_INTERNAL_TRACE_INJECTED_EXPR( \
__VA_ARGS__))) { \
} else \
switch (0) \
default: \
Expand Down
28 changes: 26 additions & 2 deletions nth/meta/sequence.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,18 @@ struct Sequence {
Sequence<>());
}

template <size_t N>
static constexpr auto chunk() requires(size() % N == 0) {
if constexpr (empty()) {
return Sequence<>{};
} else {
return []<size_t... Ns>(std::integer_sequence<size_t, Ns...>) {
return Sequence<select<Ns...>()>{} + drop<N>().template chunk<N>();
}
(std::make_index_sequence<N>{});
}
}

static constexpr auto unique() {
if constexpr (empty()) {
return Sequence<>{};
Expand All @@ -102,6 +114,19 @@ struct Sequence {
return typename split_type::template tail<Sequence>{};
}

template <size_t N = 1>
[[nodiscard]] static constexpr auto drop() requires(sizeof...(Vs) >= N) {
if constexpr (N == 1) {
using split_type = SplitFirst<Vs...>;
return typename split_type::template tail<Sequence>{};
} else {
return []<size_t... Ns>(std::integer_sequence<size_t, Ns...>) {
return select<(N + Ns)...>();
}
(std::make_index_sequence<sizeof...(Vs) - N>{});
}
}

template <size_t... Ns>
static constexpr auto select() {
return Sequence<__type_pack_element<Ns, TypeWrap<Vs>...>::value...>{};
Expand Down Expand Up @@ -207,8 +232,7 @@ template <auto... Vs>
inline constexpr internal_meta::Sequence<Vs...> sequence;

template <unsigned N>
static constexpr auto index_sequence =
internal_meta::IndexSequence<N>::value;
static constexpr auto index_sequence = internal_meta::IndexSequence<N>::value;

} // namespace nth

Expand Down
20 changes: 17 additions & 3 deletions nth/meta/sequence_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ static_assert(nth::sequence<1>.head() == 1);
static_assert(nth::sequence<2, 3, 4>.head() == 2);
static_assert(nth::sequence<1>.tail() == nth::sequence<>);
static_assert(nth::sequence<2, 3, 4>.tail() == nth::sequence<3, 4>);
static_assert(nth::sequence<1>.drop<1>() == nth::sequence<>);
static_assert(nth::sequence<2, 3, 4>.drop<1>() == nth::sequence<3, 4>);
static_assert(nth::sequence<1>.drop<0>() == nth::sequence<1>);
static_assert(nth::sequence<2, 3, 4>.drop<0>() == nth::sequence<2, 3, 4>);
static_assert(nth::sequence<2, 3, 4>.drop<2>() == nth::sequence<4>);

static_assert(not nth::sequence<>.any<[](auto x) { return x % 2 == 0; }>());
static_assert(not nth::sequence<1>.any<[](auto x) { return x % 2 == 0; }>());
Expand All @@ -61,9 +66,9 @@ static_assert(nth::sequence<>.all<[](auto x) { return x % 2 == 0; }>());
static_assert(not nth::sequence<1>.all<[](auto x) { return x % 2 == 0; }>());
static_assert(not nth::sequence<1, 3>.all<[](auto x) { return x % 2 == 0; }>());

static_assert( nth::sequence<2>.all<[](auto x) { return x % 2 == 0; }>());
static_assert( nth::sequence<2, 4>.all<[](auto x) { return x % 2 == 0; }>());
static_assert(not nth::sequence<1, 2>.all<[](auto x) { return x % 2 == 0; }>());
static_assert(nth::sequence<2>.all<[](auto x) { return x % 2 == 0; }>());
static_assert(nth::sequence<2, 4>.all<[](auto x) { return x % 2 == 0; }>());
static_assert(not nth::sequence<1, 2>.all<[](auto x) { return x % 2 == 0; }>());

static_assert(nth::sequence<>.unique() == nth::sequence<>);
static_assert(nth::sequence<1>.unique() == nth::sequence<1>);
Expand Down Expand Up @@ -103,6 +108,15 @@ static_assert(nth::sequence<1, 2>.get<0>() == 1);
static_assert(nth::sequence<1, 2, 3>.get<1>() == 2);
static_assert(nth::sequence<1, 2, 3, 1, 2, 3>.get<4>() == 2);

static_assert(nth::sequence<>.chunk<1>() == nth::sequence<>);
static_assert(nth::sequence<>.chunk<2>() == nth::sequence<>);
static_assert(nth::sequence<0, 1, 2, 3>.chunk<2>() ==
nth::sequence<nth::sequence<0, 1>, nth::sequence<2, 3>>);
static_assert(nth::sequence<0, 1, 2, 3, 4, 5>.chunk<2>() ==
nth::sequence<nth::sequence<0, 1>, nth::sequence<2, 3>,
nth::sequence<4, 5>>);
static_assert(nth::sequence<0, 1, 2, 3, 4, 5>.chunk<3>() ==
nth::sequence<nth::sequence<0, 1, 2>, nth::sequence<3, 4, 5>>);
} // namespace

int main() {
Expand Down
16 changes: 11 additions & 5 deletions nth/meta/type.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ struct Type {
return TypeId(+[] { return std::string_view(Name); });
}

template <std::convertible_to<T> U>
static constexpr auto cast(U&& u) {
return static_cast<T>(std::forward<U>(u));
}

static constexpr Type<std::decay_t<T>> decayed() { return {}; }

static constexpr Type<std::remove_reference_t<T>> without_reference() {
Expand Down Expand Up @@ -116,8 +121,8 @@ struct Type {
return os << std::string_view(name());
}

private:
static constexpr auto Name = Type::name();
private:
static constexpr auto Name = Type::name();
};

template <typename T>
Expand All @@ -127,7 +132,7 @@ std::false_type IsTypeImpl(...);
template <typename R, typename... Parameters>
struct FunctionSignature<R(Parameters...)> {
static constexpr Type<R> return_type;
static constexpr auto parameters = sequence<Type<Parameters>{}...>;
static constexpr auto parameters = sequence<Type<Parameters>{}...>;
};

} // namespace internal_type
Expand All @@ -149,15 +154,16 @@ using type_t = typename decltype(t)::type;
// useful in two common scenarios: First, when the you need to retrieve the
// first element of a pack (which could alternately be computed via
// `nth::type_t<nth::type_sequence<Pack...>.head()>`). Second, when you want to
// repeat the same type for each element of a pack, you can use
// repeat the same type for each element of a pack, you can use
//
// ```
// nth::first_t<T, Pack>...
// ```
// where you might otherwise need to coerce the cumbersome
//
// ```
// nth::type_sequence<Pack...>.template transform<[](auto) { return nth::type<T>; }>();
// nth::type_sequence<Pack...>.template transform<[](auto) { return
// nth::type<T>; }>();
// ```
// back into a pack.
template <typename T, typename...>
Expand Down
9 changes: 9 additions & 0 deletions nth/meta/type_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,15 @@ static_assert(nth::type<int(bool)>.decayed() == nth::type<int (*)(bool)>);
static_assert(nth::type<int(bool (&)[3])>.decayed() ==
nth::type<int (*)(bool (&)[3])>);

// cast
static_assert(nth::type<int>.cast(true) == 1);
struct A {};
struct B {
constexpr B(A) : value(17) {}
int value;
};
static_assert(nth::type<B>.cast(A{}).value == 17);

// type_t
static_assert(nth::type<nth::type_t<nth::type<int>>> == nth::type<int>);
static_assert(nth::type<nth::type_t<nth::type<bool>>> == nth::type<bool>);
Expand Down

0 comments on commit ed3df86

Please sign in to comment.