Skip to content

Commit

Permalink
Merge pull request #139 from elbeno/unambiguous-tuple
Browse files Browse the repository at this point in the history
🐛 Fix possible ambiguity in tuple indexing
  • Loading branch information
lukevalenty authored Sep 23, 2024
2 parents 5e3a178 + 3be1ad9 commit 66f25a0
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 54 deletions.
55 changes: 1 addition & 54 deletions include/stdx/tuple.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,7 @@ template <auto I, typename... Ts> constexpr auto index_out_of_bounds() {
} // namespace error

namespace detail {
template <std::size_t, typename...> struct element;

template <typename T>
concept derivable = std::is_class_v<T>;
template <typename T>
concept nonderivable = not std::is_class_v<T>;

template <std::size_t Index, nonderivable T, typename... Ts>
struct element<Index, T, Ts...> {
template <std::size_t Index, typename T, typename... Ts> struct element {
#if __has_builtin(__type_pack_element)
using type = T;
#else
Expand Down Expand Up @@ -117,51 +109,6 @@ struct element<Index, T, Ts...> {
element const &) = default;
};

template <std::size_t Index, derivable T, typename... Ts>
struct element<Index, T, Ts...> : T {
#if __has_builtin(__type_pack_element)
using type = T;
#else
constexpr static auto ugly_Value(index_constant<Index>) -> T;

[[nodiscard]] constexpr auto
ugly_iGet_clvr(index_constant<Index>) const & noexcept -> T const & {
return *this;
}
[[nodiscard]] constexpr auto
ugly_iGet_lvr(index_constant<Index>) & noexcept -> T & {
return *this;
}
[[nodiscard]] constexpr auto
ugly_iGet_rvr(index_constant<Index>) && noexcept -> T && {
return std::move(*this);
}
#endif

template <typename U>
requires(std::is_same_v<U, T> or ... or std::is_same_v<U, Ts>)
[[nodiscard]] constexpr auto
ugly_tGet_clvr(tag_constant<U> *) const & noexcept -> T const & {
return *this;
}
template <typename U>
requires(std::is_same_v<U, T> or ... or std::is_same_v<U, Ts>)
[[nodiscard]] constexpr auto
ugly_tGet_lvr(tag_constant<U> *) & noexcept -> T & {
return *this;
}
template <typename U>
requires(std::is_same_v<U, T> or ... or std::is_same_v<U, Ts>)
[[nodiscard]] constexpr auto
ugly_tGet_rvr(tag_constant<U> *) && noexcept -> T && {
return std::move(*this);
}

constexpr auto ugly_Value_clvr() const & -> T const & { return *this; }
constexpr auto ugly_Value_lvr() & -> T & { return *this; }
constexpr auto ugly_Value_rvr() && -> T && { return std::move(*this); }
};

template <typename Op, typename Value> struct fold_helper {
Op op;
Value value;
Expand Down
8 changes: 8 additions & 0 deletions test/tuple.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -442,3 +442,11 @@ TEST_CASE("one_of", "[tuple]") {
static_assert(stdx::one_of{1, 2, 3} == stdx::one_of{3, 4, 5});
static_assert(stdx::one_of{1, 2, 3} != stdx::one_of{4, 5, 6});
}

TEST_CASE("indexing unambiguously", "[tuple]") {
using namespace stdx::literals;

constexpr auto t = stdx::tuple{42, stdx::tuple{17}};
static_assert(t[0_idx] == 42);
static_assert(t[1_idx][0_idx] == 17);
}

0 comments on commit 66f25a0

Please sign in to comment.