@@ -210,7 +210,7 @@ struct complement_sorted_list_<tuple<S0, S ...>, tuple<T0, T ...>>
210210 using type = cons<T0, complement_sorted_list<tuple<S0, S ...>, tuple<T ...>>>;
211211};
212212
213- // Like complement_list where the second argument is [0 .. end-1].
213+ // Like complement_list where the second arg is [0 .. end-1].
214214template <class S , int end> using complement = complement_sorted_list<S, iota<end>>;
215215
216216// Prepend element to each of a list of lists.
@@ -277,10 +277,9 @@ struct mapanticomb<std::tuple<C ...>, D>
277277 using type = std::tuple<typename anticomb<C, D>::type ...>;
278278};
279279
280- template <int D, int O>
281- struct choose_
280+ template <int D, int O> struct choose_
282281{
283- static_assert (D>=O, " Bad dimension or form order ." );
282+ static_assert (D>=O, " Bad args to choose_ ." );
284283 using type = combs<iota<D>, O>;
285284};
286285
@@ -289,7 +288,7 @@ template <int D, int O> using choose = typename choose_<D, O>::type;
289288template <int D, int O> requires ((D>1 ) && (2 *O>D))
290289struct choose_<D, O>
291290{
292- static_assert (D>=O, " Bad dimension or form order ." );
291+ static_assert (D>=O, " Bad args to choose_ ." );
293292 using type = typename mapanticomb<choose<D, D-O>, D>::type;
294293};
295294
@@ -342,15 +341,41 @@ struct default_init_allocator: public A
342341
343342template <class T > using vector_default_init = std::vector<T, default_init_allocator<T>>;
344343
344+ // FIXME c++26 p2841 ?
345+ #define RA_IS_DEF (NAME, PRED ) \
346+ template <class A > constexpr bool RA_JOIN (NAME, _def) = requires { requires PRED; }; \
347+ template <class A > concept NAME = RA_JOIN(NAME, _def)<std::decay_t < A >>;
348+
349+ // Contextual len, a unique object.
350+ constexpr struct Len
351+ {
352+ consteval static rank_t rank () { return 0 ; }
353+ [[noreturn]] consteval static void len_out_of_context () { std::abort (); }
354+ consteval static dim_t len_s (int k) { len_out_of_context (); }
355+ consteval static dim_t len (int k) { len_out_of_context (); }
356+ consteval static dim_t step (int k) { len_out_of_context (); }
357+ consteval static void adv (rank_t k, dim_t d) { len_out_of_context (); }
358+ consteval static bool keep (dim_t st, int z, int j) { len_out_of_context (); }
359+ consteval dim_t operator *() const { len_out_of_context (); }
360+ consteval static int save () { len_out_of_context (); }
361+ consteval static void load (int ) { len_out_of_context (); }
362+ consteval static void mov (dim_t d) { len_out_of_context (); }
363+ } len;
364+
365+ template <class E > struct WLen ; // defined in ply.hh. FIXME C++ p2481
366+ template <class E > concept has_len = requires (int ln, E && e) { WLen<std::decay_t <E>>::f (ln, RA_FW (e)); };
367+ RA_IS_DEF (is_special, false ) // rank-0 types that we don't want reduced.
368+ template <has_len E> constexpr bool is_special_def<E> = true ;
369+
345370template <class A >
346- concept Iterator = requires (A a, rank_t k, dim_t d, rank_t i, rank_t j )
371+ concept Iterator = requires (A a, rank_t k, dim_t d, rank_t i)
347372{
348373 { a.rank () } -> std::same_as<rank_t >;
349374 { std::decay_t <A>::len_s (k) } -> std::same_as<dim_t >;
350375 { a.len (k) } -> std::same_as<dim_t >;
351376 { a.adv (k, d) } -> std::same_as<void >;
352377 { a.step (k) };
353- { a.keep (d, i, j ) } -> std::same_as<bool >;
378+ { a.keep (d, k, i ) } -> std::same_as<bool >;
354379 { a.save () };
355380 { a.load (std::declval<decltype (a.save ())>()) } -> std::same_as<void >;
356381 { a.mov (d) } -> std::same_as<void >;
@@ -362,16 +387,12 @@ concept Slice = requires (A a)
362387{
363388 { a.rank () } -> std::same_as<rank_t >;
364389 { a.iter () } -> Iterator;
365- { a.data () }; // -> has_len || std::bidirectional_iterator;
390+ requires has_len< decltype ( a.data ())> || std::bidirectional_iterator< decltype (a. data ())> ;
366391 { a.dimv };
367392};
368393
369- // FIXME c++26 p2841 ?
370- #define RA_IS_DEF (NAME, PRED ) \
371- template <class A > constexpr bool RA_JOIN (NAME, _def) = requires { requires PRED; }; \
372- template <class A > concept NAME = RA_JOIN(NAME, _def)<std::decay_t < A >>;
373-
374- RA_IS_DEF (is_scalar, !std::is_pointer_v<A> && std::is_scalar_v<A> || is_ctype<A>)
394+ RA_IS_DEF (is_scalar, !std::is_pointer_v<A> && std::is_scalar_v<A>);
395+ template <class T , T v> constexpr bool is_scalar_def<std::integral_constant<T, v>> = is_scalar<T>;
375396template <> constexpr bool is_scalar_def<std::strong_ordering> = true ;
376397template <> constexpr bool is_scalar_def<std::weak_ordering> = true ;
377398template <> constexpr bool is_scalar_def<std::partial_ordering> = true ;
@@ -414,10 +435,9 @@ rank(auto const & v)
414435 }
415436}
416437
417- // all args rank 0 (apply immediately), but at least one ra:: (disambiguate scalar version).
438+ // All args rank 0 (apply immediately), but at least one ra:: (disambiguate scalar version).
418439template <class A > concept is_ra_pos = is_ra<A> && 0 !=rank_s<A>();
419440template <class A > concept is_ra_0 = (is_ra<A> && 0 ==rank_s<A>()) || is_scalar<A>;
420- RA_IS_DEF (is_special, false ) // rank-0 types that we don't want reduced.
421441template <class ... A> constexpr bool toreduce = (!is_scalar<A> || ...) && ((is_ra_0<A> && !is_special<A>) && ...);
422442template <class ... A> constexpr bool tomap = ((is_ra_pos<A> || is_special<A>) || ...) && ((is_ra<A> || is_scalar<A> || is_fov<A> || is_builtin<A>) && ...);
423443
0 commit comments