*non_constant_p = true;
return NULL_TREE;
}
- // TODO: For REFLECT_CONSTANT_* handle proxy iterators.
if (TYPE_MAIN_VARIANT (TREE_TYPE (deref)) != valuet)
{
- if (!cxx_constexpr_quiet_p (ctx))
- error_at (loc, "unexpected type %qT of iterator dereference",
- TREE_TYPE (deref));
- *non_constant_p = true;
- return NULL_TREE;
+ deref = perform_implicit_conversion (valuet, deref, tf_warning_or_error);
+ if (error_operand_p (deref))
+ {
+ *non_constant_p = true;
+ return NULL_TREE;
+ }
+ if (CLASS_TYPE_P (valuet))
+ {
+ deref = force_target_expr (valuet, deref, tf_warning_or_error);
+ if (error_operand_p (deref))
+ {
+ *non_constant_p = true;
+ return NULL_TREE;
+ }
+ }
}
+ deref = fold_build_cleanup_point_expr (TREE_TYPE (deref), deref);
+ inc = fold_build_cleanup_point_expr (void_type_node, inc);
retvec.truncate (0);
/* while (begin != end) { push (*begin); ++begin; } */
do
constexpr int x[]{1,2,3,4,5};
constexpr int y[]{11,12,13,14,15};
constexpr auto as_pair = []<typename T1, typename T2>(const std::tuple<T1, T2>& t) static
-{ return std::pair<T1, T2>(t); };
+{ return std::make_pair (std::get <0> (t), std::get <1> (t)); };
constexpr std::span spn = std::define_static_array(std::views::zip (x, y) | std::views::transform (as_pair));
-// FIXME these should pass
-// static_assert (^^decltype(spn) == ^^std::span<const std::pair<int, int>>);
-// static_assert (spn[2].first == 3);
-// static_assert (spn[2].second == 13);
+static_assert (^^decltype(spn) == ^^const std::span<const std::pair<int, int>>);
+static_assert (spn[2].first == 3);
+static_assert (spn[2].second == 13);
constexpr int x[]{1,2,3,4,5};
constexpr int y[]{11,12,13,14,15};
-constexpr auto as_pair = []<typename T1, typename T2>(const std::tuple<T1, T2>& t) static
-{ return std::pair<T1, T2>(t); };
+constexpr auto as_pair = []<typename T1, typename T2>(const std::tuple<T1, T2>& t)
+{ const auto &[x, y] = t; return std::make_pair(x, y); };
constexpr info r = reflect_constant_array(std::views::zip (x, y) | std::views::transform (as_pair));
-// FIXME this should be pass
-// static_assert (type_of (^^r) == ^^const std::pair<int, int>[5]);
-// static_assert ([: r :][2].first == 3);
-// static_assert ([: r :][2].second == 13);
-
+static_assert (type_of (r) == ^^const std::pair<int, int>[5]);
+static_assert ([: r :][2].first == 3);
+static_assert ([: r :][2].second == 13);
--- /dev/null
+// PR c++/124425
+// { dg-do compile { target c++26 } }
+// { dg-additional-options "-freflection" }
+
+#include <meta>
+
+struct A { };
+
+template <typename T>
+struct B
+{
+ using value_type = T;
+ using difference_type = int;
+ struct C
+ {
+ T i;
+ constexpr operator T () const { return i; }
+ };
+ constexpr B &operator++ () { ++i; return *this; }
+ constexpr B operator++ (int) { return B { i++ }; }
+ constexpr C operator * () const { return C { i }; }
+ constexpr bool operator== (A) const { return i == 10; }
+ constexpr B () : p (new char (42)) {}
+ constexpr B (const B &x) : i (x.i), p (new char (42)) {}
+ constexpr ~B () { delete p; }
+ int i = 0;
+ char *p;
+};
+
+template <typename T>
+struct D
+{
+ constexpr B <T> begin () const { return {}; };
+ constexpr A end () const { return {}; };
+};
+
+struct E
+{
+ constexpr E (int x) : a (x), b (x + 1), c (x + 2) {}
+ constexpr E (const E &x) : a (x.a), b (x.b), c (x.c) {}
+ constexpr ~E () {}
+ int a, b, c;
+};
+
+constexpr auto &d = [: std::meta::reflect_constant_array (D <int> {}) :];
+constexpr auto &e = [: std::meta::reflect_constant_array (D <E> {}) :];
+consteval {
+ for (int i = 0; i < 10; ++i)
+ if (d[i] != i || e[i].a != i || e[i].b != i + 1 || e[i].c != i + 2)
+ throw 1;
+}
--- /dev/null
+// PR c++/124425
+// { dg-do compile { target c++26 } }
+// { dg-additional-options "-freflection" }
+
+#include <meta>
+
+constexpr auto &s = [: std::meta::reflect_constant_array (std::vector { true, false, true }) :];
+static_assert (s[0] && !s[1] && s[2]);