Skip to content

Commit

Permalink
Pack discriminator only operates on types and const auto&.
Browse files Browse the repository at this point in the history
This had inconsistent behaviour across compilers, and Ubuntu + C++20 specifically breaks.

A similar issue was encountered a while back when trying to support Windows, which was what motivated the "diminished" forms.

PiperOrigin-RevId: 712294962
  • Loading branch information
jwhpryor authored and copybara-github committed Jan 10, 2025
1 parent cedfa95 commit 72e447d
Show file tree
Hide file tree
Showing 5 changed files with 15 additions and 86 deletions.
41 changes: 1 addition & 40 deletions metaprogramming/deep_equal_diminished_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,6 @@ struct A {
template <typename... Ts>
struct Type {};

template <const auto... Vs>
struct Auto {};

template <const auto... Vs>
struct AutoRef {};

template <const auto&... Vs>
struct ConstAutoRef {};

Expand All @@ -65,43 +59,10 @@ static_assert(!DeepEqualDiminished_v<std::tuple<Type<int, int>>,
std::tuple<std::tuple<int, int>>>);

////////////////////////////////////////////////////////////////////////////////
// Autos.
////////////////////////////////////////////////////////////////////////////////
static_assert(
!DeepEqualDiminished_v<std::tuple<Type<int>>, std::tuple<Auto<'a'>>>);
static_assert(
DeepEqualDiminished_v<std::tuple<Auto<'a'>>, std::tuple<Auto<'a'>>>);
static_assert(
!DeepEqualDiminished_v<std::tuple<Auto<'a'>>, std::tuple<Auto<'b'>>>);
static_assert(
!DeepEqualDiminished_v<std::tuple<Auto<'a'>>, std::tuple<Auto<'a', 'a'>>>);

static_assert(DeepEqualDiminished_v<Auto<1>, Auto<1>>);
static_assert(!DeepEqualDiminished_v<Auto<1>, Auto<2>>);
static_assert(!DeepEqualDiminished_v<Auto<1>, Auto<1, 1>>);

////////////////////////////////////////////////////////////////////////////////
// Autos Refs.
// Const Autos Refs.
////////////////////////////////////////////////////////////////////////////////
const auto a = 'a';
const auto b = 'b';

static_assert(
!DeepEqualDiminished_v<std::tuple<Type<int>>, std::tuple<AutoRef<a>>>);
static_assert(
DeepEqualDiminished_v<std::tuple<AutoRef<a>>, std::tuple<AutoRef<a>>>);
static_assert(
!DeepEqualDiminished_v<std::tuple<AutoRef<a>>, std::tuple<AutoRef<b>>>);
static_assert(
!DeepEqualDiminished_v<std::tuple<AutoRef<a>>, std::tuple<AutoRef<a, a>>>);

static_assert(DeepEqualDiminished_v<AutoRef<a>, AutoRef<a>>);
static_assert(!DeepEqualDiminished_v<AutoRef<a>, AutoRef<b>>);
static_assert(!DeepEqualDiminished_v<AutoRef<a>, AutoRef<a, a>>);

////////////////////////////////////////////////////////////////////////////////
// Const Autos Refs.
////////////////////////////////////////////////////////////////////////////////
static_assert(
!DeepEqualDiminished_v<std::tuple<Type<int>>, std::tuple<ConstAutoRef<a>>>);
static_assert(DeepEqualDiminished_v<std::tuple<ConstAutoRef<a>>,
Expand Down
2 changes: 1 addition & 1 deletion metaprogramming/next.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ struct EndConstRefVal;
// |T| must always be a container of a single kind of template expression.
template <typename T>
using Next_t =
typename PackDiscriminatedForward<NextType, NextVal,
typename PackDiscriminatedForward<NextType,
NextConstRefVal>::template type<T>;

} // namespace jni::metaprogramming
Expand Down
13 changes: 10 additions & 3 deletions metaprogramming/next_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ using ::jni::metaprogramming::NextConstRefVal; // NOLINT
using ::jni::metaprogramming::NextType; // NOLINT
using ::jni::metaprogramming::NextVal; // NOLINT

namespace jni::metaprogramming {

////////////////////////////////////////////////////////////////////////////////
// Type tests.
////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -58,6 +60,7 @@ struct NextType<TypeCounter> {
};

static_assert(std::is_same_v<Next_t<TypeCounter_t<0, 3>>, TypeCounter_t<1, 3>>);

static_assert(
std::is_same_v<Next_t<Next_t<TypeCounter_t<0, 3>>>, TypeCounter_t<2, 3>>);
static_assert(std::is_same_v<Next_t<Next_t<Next_t<TypeCounter_t<0, 3>>>>,
Expand Down Expand Up @@ -91,12 +94,14 @@ struct NextVal<Counter> {
using type = typename Helper<T>::type;
};

/*
static_assert(std::is_same_v<Next_t<Counter<0, 3>>, Counter<1, 3>>);
static_assert(std::is_same_v<Next_t<Next_t<Counter<0, 3>>>, Counter<2, 3>>);
static_assert(
std::is_same_v<Next_t<Next_t<Next_t<Counter<0, 3>>>>, Counter<3, 3>>);
static_assert(std::is_same_v<Next_t<Next_t<Next_t<Next_t<Counter<0, 3>>>>>,
EndVal<Counter>>);
*/

////////////////////////////////////////////////////////////////////////////////
// Const Auto& tests.
Expand All @@ -110,18 +115,18 @@ static constexpr std::size_t kTheValue0 = 0;
static constexpr std::size_t kMaxValSizeGlobal = 3;

template <>
struct ::jni::metaprogramming::NextConstRefVal<::ConstRefCounter> {
struct NextConstRefVal<ConstRefCounter> {
template <typename T>
struct Helper;

template <const std::size_t& I, const std::size_t& kMaxVal>
struct Helper<::ConstRefCounter<I, kMaxVal>> {
struct Helper<ConstRefCounter<I, kMaxVal>> {
static constexpr std::size_t kNextVal = I + 1;
using type = ConstRefCounter<kNextVal, kMaxVal>;
};

template <const std::size_t& kMaxVal>
struct Helper<::ConstRefCounter<kMaxVal, kMaxVal>> {
struct Helper<ConstRefCounter<kMaxVal, kMaxVal>> {
using type = EndConstRefVal<ConstRefCounter>;
};

Expand All @@ -138,3 +143,5 @@ static_assert(
Next_t<
Next_t<Next_t<ConstRefCounter<kTheValue0, kMaxValSizeGlobal>>>>::val ==
3);

} // namespace jni::metaprogramming
25 changes: 3 additions & 22 deletions metaprogramming/pack_discriminator.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ namespace jni::metaprogramming {
enum class PackType {
NOT_CONTAINER,
TYPES,
AUTO,
AUTO_REF,
CONST_AUTO_REF,
};

Expand All @@ -41,16 +39,6 @@ struct PackDiscrimator {
static constexpr PackType val = PackType::TYPES;
};

template <template <auto...> class Container, auto... Vs>
struct Helper<Container<Vs...>> {
static constexpr PackType val = PackType::AUTO;
};

template <template <auto&...> class Container, auto&... Vs>
struct Helper<Container<Vs...>> {
static constexpr PackType val = PackType::AUTO_REF;
};

template <template <const auto&...> class Container, const auto&... Vs>
struct Helper<Container<Vs...>> {
static constexpr PackType val = PackType::CONST_AUTO_REF;
Expand All @@ -65,10 +53,9 @@ static constexpr PackType PackDiscriminator_e =
PackDiscrimator::template val<T>;

// Metafunction to forward a containerized pack to a compatible container.
template <template <template <typename...> class> class TypesContainer,
template <template <auto...> class> class AutoContainer,
template <template <const auto&...> class>
class ConstAutoRefContainer>
template <
template <template <typename...> class> class TypesContainer,
template <template <const auto&...> class> class ConstAutoRefContainer>
struct PackDiscriminatedForward {
template <typename T>
struct Helper;
Expand All @@ -79,12 +66,6 @@ struct PackDiscriminatedForward {
typename TypesContainer<Container>::template type<Container<Ts...>>;
};

template <template <auto...> class Container, auto... vs>
struct Helper<Container<vs...>> {
using type =
typename AutoContainer<Container>::template type<Container<vs...>>;
};

template <template <const auto&...> class Container, const auto&... vs>
struct Helper<Container<vs...>> {
using type = typename ConstAutoRefContainer<Container>::template type<
Expand Down
20 changes: 0 additions & 20 deletions metaprogramming/pack_discriminator_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,6 @@ namespace {
using ::jni::metaprogramming::PackDiscriminator_e;
using ::jni::metaprogramming::PackType;

int a = 1;
int b = 1;

static constexpr bool kVal1 = false;
static constexpr bool kVal2 = false;

Expand All @@ -32,33 +29,16 @@ struct NonContainer {};
template <typename... Ts>
struct A {};

template <auto... Vs>
struct B {};

template <auto&... Vs>
struct C {};

template <const auto&... Vs>
struct D {};

// See class comment.
// static_assert(PackDiscriminator_e<B<>> == PackType::AUTO);
// static_assert(PackDiscriminator_e<C<>> == PackType::AUTO_REF);
// static_assert(PackDiscriminator_e<D<>> == PackType::CONST_AUTO_REF);

static_assert(PackDiscriminator_e<int> == PackType::NOT_CONTAINER);
static_assert(PackDiscriminator_e<NonContainer> == PackType::NOT_CONTAINER);

static_assert(PackDiscriminator_e<A<>> == PackType::TYPES);
static_assert(PackDiscriminator_e<A<float>> == PackType::TYPES);
static_assert(PackDiscriminator_e<A<int, float>> == PackType::TYPES);

static_assert(PackDiscriminator_e<B<0>> == PackType::AUTO);
static_assert(PackDiscriminator_e<B<0, 1>> == PackType::AUTO);

static_assert(PackDiscriminator_e<C<a>> == PackType::AUTO_REF);
static_assert(PackDiscriminator_e<C<a, b>> == PackType::AUTO_REF);

static_assert(PackDiscriminator_e<D<kVal1>> == PackType::CONST_AUTO_REF);
static_assert(PackDiscriminator_e<D<kVal1, kVal2>> == PackType::CONST_AUTO_REF);

Expand Down

0 comments on commit 72e447d

Please sign in to comment.