0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

25.3 Iterator requirements [iterator.requirements] C++N4910:2022 (645) p974.cpp

Posted at

はじめに(Introduction)

N4910 Working Draft, Standard for Programming Language C++

n4910は、ISO/IEC JTC1 SC22 WG21の作業原案(Working Draft)です。
公式のISO/IEC 14882原本ではありません。
ISO/IEC JTC1 SC22 WG21では、可能な限り作業文書を公開し、幅広い意見を求めています。
一連の記事はコード断片をコンパイルできる形にする方法を検討してコンパイル、リンク、実行して、規格案の原文と処理系(g++, Clang++)との違いを確認し、技術内容を検討し、ISO/IEC JTC1 SC22 WG21にフィードバックするために用います。
また、CERT C++, MISRA C++等のコーディング標準のコード断片をコンパイルする際の参考にさせていただこうと考えています。CERT C++, MISRA C++が標準化の動きとの時間的なずれがあれば確認できれば幸いです。また、boostライブラリとの関連、Linux OS, TOPPERSカーネル、g++(GCC), clang++(LLVM)との関係も調査中です。
何か、抜け漏れ、耳より情報がありましたらおしらせくださると幸いです。

<この項は書きかけです。順次追記します。>

背景(back ground)

C/C++でコンパイルエラーが出ると、途方にくれることがしばしばあります。
何回かに1回は、該当するエラーが検索できます。
ただ、条件が違っていて、そこでの修正方法では目的を達成しないこともしばしばです。いろいろな条件のコンパイルエラーとその対応方法について、広く記録することによって、いつか同じエラーに遭遇した時にやくに立つことを目指しています。

この半年の間で、三度、自分のネットでの記録に助けられたことがあります。
また過去に解決できなかった記録を10種類以上、最近になって解決できたことがあります。それは、主に次の3つの情報に基づいています。

cpprefjp - C++日本語リファレンス

コンパイラの実装状況

また
https://researchmap.jp/joub9b3my-1797580/#_1797580
に記載したサイトのお世話になっています。

作業方針(sequence)

Clang++では-std=c++03, C++2bの2種類
g++では-std=c++03, c++2bの2種類
でコンパイルし、

1)コンパイルエラーを収集する。
2)コンパイルエラーをなくす方法を検討する。
コンパイルエラーになる例を示すだけが目的のコードは、コンパイルエラーをなくすのではなく、コンパイルエラーの種類を収集するだけにする。
文法を示すのが目的のコード場合に、コンパイルエラーをなくすのに手間がかかる場合は、順次作業します。
3)リンクエラーをなくす方法を検討する。
文法を示すのが目的のコード場合に、リンクエラーをなくすのに手間がかかる場合は、順次作業します。
4)意味のある出力を作る。
コンパイル、リンクが通っても、意味のある出力を示そうとすると、コンパイル・リンクエラーが出て収拾できそうにない場合がある。順次作業します。

1)だけのものから4)まで進んだものと色々ある状態です。一歩でも前に進むご助言をお待ちしています。「検討事項」の欄に現状を記録するようにしています。

C++N4910:2022 Standard Working Draft on ISO/IEC 14882(0) sample code compile list

C++N4741, 2018 Standard Working Draft on ISO/IEC 14882 sample code compile list

C++N4606, 2016符号断片編纂一覧(example code compile list)

C++N4606, 2016 Working Draft 2016, ISO/IEC 14882, C++ standard(1) Example code compile list
https://qiita.com/kaizen_nagoya/items/df5d62c35bd6ed1c3d43/

C++N3242, 2011 sample code compile list on clang++ and g++

編纂器(Compiler)

clang++ --version

Debian clang version 14.0.5-++20220610033153+c12386ae247c-1~exp1~20220610153237.151
Target: x86_64-pc-linux-gnu, Thread model: posix, InstalledDir: /usr/bin

g++- --version

g++ (GCC) 12.1.0 Copyright (C) 2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

25.3 Iterator requirements [iterator.requirements] C++N4910:2022 (645) p974.cpp

算譜(source code)

p974.cpp
// C++N4910 Committee Draft, Standard for Programming Language C++
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/n4910.pdf
const char * n4910 = "25.3 Iterator requirements [iterator.requirements] C++N4910:2022 (645) p974.cpp";
// Debian clang version 14.0.5-++20220610033153+c12386ae247c-
// g++ (GCC) 12.1.0 Copyright (C) 2022 Free Software Foundation, Inc.
// Edited by Dr. OGAWA Kiyoshi. Compile procedure and results record.
// C++N4910:2022 Standard Working Draft on ISO/IEC 14882(0) sample code compile list
// https://qiita.com/kaizen_nagoya/items/fc957ddddd402004bb91

#include "N4910.h"

using namespace std;

// 25.3.1 In general [iterator.requirements.general]
// Iterators are a generalization of pointers that allow a C++ program to work with different data structures (for example, containers and ranges) in a uniform manner. To be able to construct template algorithms that work correctly and efficiently on different types of data structures, the library formalizes not just the interfaces but also the semantics and complexity assumptions of iterators. An input iterator i supports the expression *i, resulting in a value of some object type T, called the value type of the iterator. An output
// iterator i has a non-empty set of types that are indirectly_writable to the iterator; for each such type T, the expression *i = o is valid where o is a value of type T. For every iterator type X, there is a corresponding signed integer-like type (25.3.4.4) called the difference type of the iterator.
// Since iterators are an abstraction of pointers, their semantics are a generalization of most of the semantics of pointers in C++. This ensures that every function template that takes iterators works as well with regular pointers. This document defines six categories of iterators, according to the operations defined on them: input iterators, output iterators, forward iterators, bidirectional iterators, random access iterators, and contiguous iterators, as shown in Table 81.
//  The six categories of iterators correspond to the iterator concepts
//   Contiguous → Random Access → Bidirectional → Forward → Input → Output
//    — input_iterator (25.3.4.9),
// — output_iterator (25.3.4.10),
// — forward_iterator (25.3.4.11),
// — bidirectional_iterator (25.3.4.12),
// — random_access_iterator (25.3.4.13), and — contiguous_iterator
// Forward iterators meet all the requirements of input iterators and can be used whenever an input iterator is specified; Bidirectional iterators also meet all the requirements of forward iterators and can be used whenever a forward iterator is specified; Random access iterators also meet all the requirements of bidirectional iterators and can be used whenever a bidirectional iterator is specified; Contiguous iterators also meet all the requirements of random access iterators and can be used whenever a random access iterator is specified.
//  Iterators that further meet the requirements of output iterators are called mutable iterators. Nonmutable iterators are referred to as constant iterators.
// In addition to the requirements in this subclause, the nested typedef-names specified in 25.3.2.3 shall be provided for the iterator type.
// [Note 1: Either the iterator type must provide the typedef-names directly (in which case iterator_traits pick them up automatically), or an iterator_traits specialization must provide them.
//  Just as a regular pointer to an array guarantees that there is a pointer value pointing past the last element of the array, so for any iterator type there is an iterator value that points past the last element of a corresponding sequence. Such a value is called a past-the-end value. Values of an iterator i for which the expression *i is defined are called dereferenceable. The library never assumes that past-the-end values are dereferenceable. Iterators can also have singular values that are not associated with any sequence. Results of most expressions are undefined for singular values; the only exceptions are destroying an iterator that holds a singular value, the assignment of a non-singular value to an iterator that holds a singular value, and, for iterators that meet the Cpp17DefaultConstructible requirements, using a value-initialized iterator as the source of a copy or move operation.
// respectively. The generic term iterator refers to any type that models the input_or_output_iterator concept (25.3.4.6).
// [Note 2: This guarantee is not offered for default-initialization, although the distinction only matters for types with trivial default constructors such as pointers or aggregates holding pointers.
// In these cases the singular value is overwritten the same way as any other value. Dereferenceable values are always non-singular.
//  Most of the library’s algorithmic templates that operate on data structures have interfaces that use ranges. A range is an iterator and a sentinel that designate the beginning and end of the computation, or an iterator and a count that designate the beginning and the number of elements to which the computation is to be applied.218
//  An iterator and a sentinel denoting a range are comparable. A range [i, s) is empty if i == s; otherwise, [i, s) refers to the elements in the data structure starting with the element pointed to by i and up to but not including the element, if any, pointed to by the first iterator j such that j == s.
//  A sentinel s is called reachable from an iterator i if and only if there is a finite sequence of applications of the expression ++i that makes i == s. If s is reachable from i, [i, s) denotes a valid range.
//  A counted range i + [0, n) is empty if n == 0; otherwise, i + [0, n) refers to the n elements in the data structure starting with the element pointed to by i and up to but not including the element, if any, pointed to by the result of n applications of ++i. A counted range i+[0, n) is valid if and only if n == 0; or n is positive, i is dereferenceable, and ++i + [0, --n) is valid.
//  The result of the application of library functions to invalid ranges is undefined.
//  All the categories of iterators require only those functions that are realizable for a given category in constant time (amortized). Therefore, requirement tables and concept definitions for the iterators do not specify complexity.
// Destruction of a non-forward iterator may invalidate pointers and references previously obtained from that iterator.
//  An invalid iterator is an iterator that may be singular.219
//  Iterators are called constexpr iterators if all operations provided to meet iterator category requirements are
constexpr functions.
// [Note 3: For example, the types “pointer to int” and reverse_iterator<int*> are constexpr iterators.
// 25.3.2 Associated types [iterator.assoc.types]
// 25.3.2.1 Incrementable traits [incrementable.traits]
//  To implement algorithms only in terms of incrementable types, it is often necessary to determine the difference type that corresponds to a particular incrementable type. Accordingly, it is required that if WI is the name of a type that models the weakly_incrementable concept (25.3.4.4), the type
iter_difference_t<WI>
// be defined as the incrementable type’s difference type.
namespace std {
template<class> struct incrementable_traits { };
template<class T>
requires is_object_v<T>
struct incrementable_traits<T*> {
    using difference_type = ptrdiff_t;
};
template<class I>
struct incrementable_traits<const I>
    : incrementable_traits<I> { };
template<class T>
requires requires { typename T::difference_type; }
// — incrementable_traits<RI>::difference_type if iterator_traits<RI> names a specialization gen- erated from the primary template, and
struct incrementable_traits<T> {
    using difference_type = typename T::difference_type;
};
template<class T>
requires (!requires { typename T::difference_type; } &&
requires(const T& a, const T& b) {
    {
        a - b
    }
    -> integral;
})
struct incrementable_traits<T> {
    using difference_type = make_signed_t<decltype(declval<T>() - declval<T>())>;
};
template<class T>
using iter_difference_t = see_below;
}
//  Let RI be remove_cvref_t<I>. The type iter_difference_t<I> denotes
// — iterator_traits<RI>::difference_type otherwise.
// 25.3.2.2 Indirectly readable traits [readable.traits]
//  To implement algorithms only in terms of indirectly readable types, it is often necessary to determine the value type that corresponds to a particular indirectly readable type. Accordingly, it is required that if R is the name of a type that models the indirectly_readable concept (25.3.4.2), the type
(2.2)
//  Users may specialize incrementable_traits on program-defined types.
iter_value_t<R>
// be defined as the indirectly readable type’s value type.
template<class> struct cond_value_type { };
template<class T>
requires is_object_v<T> struct cond_value_type<T> {
    using value_type = remove_cv_t<T>;
};
// exposition only
template<class T>
concept has_member_value_type = requires { typename T::value_type; };
template<class T>
concept has_member_element_type = requires { typename T::element_type; };
template<class> struct indirectly_readable_traits { };
template<class T>
struct indirectly_readable_traits<T*>
    : cond_value_type<T> { };
template<class I>
requires is_array_v<I>
struct indirectly_readable_traits<I> {
    using value_type = remove_cv_t<remove_extent_t<I>>;
};
template<class I>
struct indirectly_readable_traits<const I>
    : indirectly_readable_traits<I> { };
template<has_member_value_type T> struct indirectly_readable_traits<T>
    : cond_value_type<typename T::value_type> { };
// exposition only // exposition only
// — indirectly_readable_traits<RI>::value_type if iterator_traits<RI> names a specialization generated from the primary template, and
template<has_member_element_type T> struct indirectly_readable_traits<T>
    : cond_value_type<typename T::element_type> { };
template<has_member_value_type T> requires has-member_element_type<T>
struct indirectly_readable_traits<T> { };
template<has_member_value_type T> requires has-member_element_type<T> &&
same_as<remove_cv_t<typename T::element_type>, remove_cv_t<typename T::value_type>>
        struct indirectly_readable_traits<T>
            : cond_value_type<typename T::value_type> { };
template<class T> using iter_value_t = see_below;
//  Let RI be remove_cvref_t<I>. The type iter_value_t<I> denotes
// — iterator_traits<RI>::value_type otherwise.
//  [Note 1: Some legacy output iterators define a nested type named value_type that is an alias for void. These types are not indirectly_readable and have no associated value types.
//  [Note 2: Smart pointers like shared_ptr<int> are indirectly_readable and have an associated value type, but a smart pointer like shared_ptr<void> is not indirectly_readable and has no associated value type.
// 25.3.2.3 Iterator traits [iterator.traits]
//  To implement algorithms only in terms of iterators, it is sometimes necessary to determine the iterator category that corresponds to a particular iterator type. Accordingly, it is required that if I is the type of an iterator, the type
iterator_traits<I>::iterator_category
// be defined as the iterator’s iterator category. In addition, the types
iterator_traits<I>::pointer
iterator_traits<I>::reference
// shall be defined as the iterator’s pointer and reference types; that is, for an iterator object a of class type, the same type as decltype(a.operator->()) and decltype(*a), respectively. The type iterator_- traits<I>::pointer shall be void for an iterator of class type I that does not support operator->. Additionally, in the case of an output iterator, the types
iterator_traits<I>::value_type
iterator_traits<I>::difference_type
iterator_traits<I>::reference
// may be defined as void.
//  The definitions in this subclause make use of the following exposition-only concepts:
template<class I> concept cpp17-iterator =
requires(I i) {
    {
        *i
    }
    -> can-reference;
    {
        ++i
    }
    -> same_as<I&>;
    {
        *i++
    }
    -> can-reference;
}
&& copyable<I>;
template<class I>
concept cpp17-input-iterator =
cpp17-iterator<I> && equality_comparable<I> && requires(I i) {
    typename incrementable_traits<I>::difference_type;
    typename indirectly_readable_traits<I>::value_type;
    typename common_reference_t<iter_reference_t<I>&&,
// Class template indirectly_readable_traits may be specialized on program-defined types.
             typename indirectly_readable_traits<I>::value_type&>;
// — If I has valid (13.10.3) member types difference_type, value_type, reference, and iterator_- category, then iterator_traits<I> has the following publicly accessible members:
    using iterator_category = typename I::iterator_category;
    typename common_reference_t<decltype(*i++)&&,
             typename indirectly_readable_traits<I>::value_type&>;
    requires signed_integral<typename incrementable_traits<I>::difference_type>;
};
template<class I>
concept cpp17-forward-iterator =
    cpp17-input-iterator<I> && constructible_from<I> && is_lvalue_reference_v<iter_reference_t<I>> && same_as<remove_cvref_t<iter_reference_t<I>>,
    typename indirectly_readable_traits<I>::value_type> &&
requires(I i) {
    {
        i++
    }
    -> convertible_to<const I&>;
    {
        *i++
    }
    -> same_as<iter_reference_t<I>>;
};
template<class I>
concept cpp17-bidirectional-iterator =
cpp17-forward-iterator<I> && requires(I i) {
    {
        --i
    }
    -> same_as<I&>;
    {
        i--
    }
    -> convertible_to<const I&>;
    {
        *i--
    }
    -> same_as<iter_reference_t<I>>;
};
template<class I>
concept cpp17-random-access-iterator =
    cpp17-bidirectional-iterator<I> && totally_ordered<I> &&
requires(I i, typename incrementable_traits<I>::difference_type n) {
    {
        i += n
    }
    -> same_as<I&>;
    {
        i -= n
    }
    -> same_as<I&>;
    {
        i+ n
    }
    ->same_as<I>;
    {
        n+ i
    }
    ->same_as<I>;
    {
        i- n
    }
    ->same_as<I>;
    {
        i - i
    }
    -> same_as<decltype(n)>;
    {
        i[n]
    }
    -> convertible_to<iter_reference_t<I>>;
};
// The members of a specialization iterator_traits<I> generated from the iterator_traits primary tem- plate are computed as follows:
using value_type = typename I::value_type;
using difference_type = typename I::difference_type;
using pointer  = see_below ;
using reference = typename I::reference;
// If the qualified-id I::pointer is valid and denotes a type, then iterator_traits<I>::pointer names that type; otherwise, it names void.
// — Otherwise, if I satisfies the exposition-only concept cpp17-input-iterator, iterator_traits<I> has the following publicly accessible members:
using iterator_category = see_below;
using value_type = typename indirectly_readable_traits<I>::value_type;
using difference_type = typename incrementable_traits<I>::difference_type;
using pointer  = see_below ;
using reference  = see_below ;
// — If the qualified-id I::pointer is valid and denotes a type, pointer names that type. Other- wise, if decltype(declval<I&>().operator->()) is well-formed, then pointer names that type. Otherwise, pointer names void.
// — If the qualified-id I::reference is valid and denotes a type, reference names that type. Otherwise, reference names iter_reference_t<I>.
// — If the qualified-id I::iterator_category is valid and denotes a type, iterator_category names that type. Otherwise, iterator_category names:
// — random_access_iterator_tag if I satisfies cpp17-random-access-iterator , or otherwise — bidirectional_iterator_tag if I satisfies cpp17-bidirectional-iterator , or otherwise
// — forward_iterator_tag if I satisfies cpp17-forward-iterator , or otherwise
// — input_iterator_tag.
// — Otherwise, if I satisfies the exposition-only concept cpp17-iterator , then iterator_traits<I> has the following publicly accessible members:
using iterator_category = output_iterator_tag;
using value_type = void;
using difference_type = see_below ;
using pointer = void;
using reference = void;
// If the qualified-id incrementable_traits<I>::difference_type is valid and denotes a type, then difference_type names that type; otherwise, it names void.
// — Otherwise, iterator_traits<I> has no members by any of the above names. used to indicate conformance to the iterator concepts (25.3.4).
// [Example 1 : To indicate conformance to the input_iterator concept but a lack of conformance to the Cpp17InputIter- ator requirements (25.3.5.3), an iterator_traits specialization might have iterator_concept denote input_- iterator_tag but not define iterator_category.
//  iterator_traits is specialized for pointers as
namespace std {
template<class T>
requires is_object_v<T>
struct iterator_traits<T*> {
    using iterator_concept  = contiguous_iterator_tag;
    using iterator_category = random_access_iterator_tag;
//  Explicit or partial specializations of iterator_traits may have a member type iterator_concept that is
};
}
using value_type = remove_cv_t<T>;
using difference_type = ptrdiff_t;
using pointer = T*;
using reference = T&;
// [Example 2: To implement a generic reverse function, a C++ program can do the following:
template<class BI>
void reverse(BI first, BI last) {
    typename iterator_traits<BI>::difference_type n =
        distance(first, last);
    --n;
    while(n > 0) {
        typename iterator_traits<BI>::value_type
        tmp = *first;
        *first++ = *--last;
        *last = tmp;
        n -= 2;
    }
}
// 25.3.3 Customization point objects [iterator.cust]
// 25.3.3.1 ranges::iter_move  [iterator.cust.move]
//  The name ranges::iter_move denotes a customization point object (16.3.3.3.6). The expression ranges::- iter_move(E) for a subexpression E is expression-equivalent to:
// — iter_move(E), if E has class or enumeration type and iter_move(E) is a well-formed expression when treated as an unevaluated operand, with overload resolution performed in a context that does not include a declaration of ranges::iter_move but does include the declaration
void iter_move();
// — Otherwise, if the expression *E is well-formed: — if *E is an lvalue, std::move(*E);
// — otherwise, *E.
// — Otherwise, ranges::iter_move(E) is ill-formed.
// [Note 1: This case can result in substitution failure when ranges::iter_move(E) appears in the immediate
// — If the qualified-id ITER_TRAITS(I)::iterator_concept is valid and names a type, then ITER_- CONCEPT(I) denotes that type.
// — Otherwise, if the qualified-id ITER_TRAITS(I)::iterator_category is valid and names a type, then ITER_CONCEPT(I) denotes that type.
// — Otherwise, if iterator_traits<I> names a specialization generated from the primary template, then ITER_CONCEPT(I) denotes random_access_iterator_tag.
// context of a template instantiation.
// If ranges::iter_move(E) is not equal to *E, the program is ill-formed, no diagnostic required.
// 25.3.3.2 ranges::iter_swap [iterator.cust.swap]
//  The name ranges::iter_swap denotes a customization point object (16.3.3.3.6) that exchanges the values
(18.4.9) denoted by its arguments.
// Let iter-exchange-move be the exposition-only function:
template<class X, class Y>
constexpr iter_value_t<X> iter-exchange-move(X&& x, Y&& y)
noexcept(noexcept(iter_value_t<X>(iter_move(x))) &&
         noexcept(*x = iter_move(y)));
// Effects: Equivalent to:
iter_value_t<X> old_value(iter_move(x));
*x = iter_move(y);
return old_value;
//  The expression ranges::iter_swap(E1, E2) for subexpressions E1 and E2 is expression-equivalent to:
// — (void)iter_swap(E1, E2), if either E1 or E2 has class or enumeration type and iter_swap(E1, E2) is a well-formed expression with overload resolution performed in a context that includes the declaration
template<class I1, class I2>
void iter_swap(I1, I2) = delete;
// and does not include a declaration of ranges::iter_swap. If the function selected by overload resolution does not exchange the values denoted by E1 and E2, the program is ill-formed, no diagnostic required.
// — Otherwise, if the types of E1 and E2 each model indirectly_readable, and if the reference types of E1 and E2 model swappable_with (18.4.9), then ranges::swap(*E1, *E2).
// — Otherwise, if the types T1 and T2 of E1 and E2 model indirectly_movable_storable<T1, T2> and indirectly_movable_storable<T2, T1>, then (void)(*E1 = iter-exchange-move(E2, E1)), except that E1 is evaluated only once.
// — Otherwise, ranges::iter_swap(E1, E2) is ill-formed.
// [Note 1 : This case can result in substitution failure when ranges::iter_swap(E1, E2) appears in the immediate
//  For a type I, let ITER_TRAITS(I) denote the type I if iterator_traits<I> names a specialization generated from the primary template. Otherwise, ITER_TRAITS(I) denotes iterator_traits<I>.
// 25.3.4 Iterator concepts [iterator.concepts]
// 25.3.4.1 General [iterator.concepts.general]
// — Otherwise, ITER_CONCEPT(I) does not denote a type.
// — If Out and T model indirectly_readable<Out> && same_as<iter_value_t<Out>, decay_t<T>>, then *o after any above assignment is equal to the value of E before the assignment.
//  [Note 1 : ITER_TRAITS enables independent syntactic determination of an iterator’s category and concept.
// [Example 1:
struct I {
    using value_type = int;
    using difference_type = int;
    int operator*() const;
    I& operator++();
    I operator++(int);
    I& operator--();
    I operator--(int);
    bool operator==(I) const;
};
// iterator_traits<I>::iterator_category denotes input_iterator_tag, and ITER_CONCEPT (I) denotes random_- access_iterator_tag. —end example]
// 25.3.4.2 Concept indirectly_readable [iterator.concept.readable]
//  Types that are indirectly readable by applying operator* model the indirectly_readable concept, including pointers, smart pointers, and iterators.
template<class In>
concept indirectly-readable-impl =
requires(const In in) {
    typename iter_value_t<In>;
    typename iter_reference_t<In>;
    typename iter_rvalue_reference_t<In>;
    {
        *in
    }
    -> same_as<iter_reference_t<In>>;
    {
        ranges::iter_move(in)
    }
    -> same_as<iter_rvalue_reference_t<In>>;
}
&&
common_reference_with<iter_reference_t<In>&&, iter_value_t<In>&> &&
common_reference_with<iter_reference_t<In>&&, iter_rvalue_reference_t<In>&&> &&
common_reference_with<iter_rvalue_reference_t<In>&&, const iter_value_t<In>&>;
template<class In>
concept indirectly_readable =
    indirectly-readable-impl<remove_cvref_t<In>>;
// Given a value i of type I, I models indirectly_readable only if the expression *i is equality-preserving.
// [Note 1: The expression *i is indirectly required to be valid via the exposition-only dereferenceable concept (25.2).
// 25.3.4.3 Concept indirectly_writable [iterator.concept.writable]
//  The indirectly_writable concept specifies the requirements for writing a value into an iterator’s referenced object.
template<class Out, class T>
concept indirectly_writable =
requires(Out&& o, T&& t) {
    *o = std::forward<T>(t); // not required to be equality-preserving
    *std::forward<Out>(o) = std::forward<T>(t); // not required to be equality-preserving const_cast<const iter_reference_t<Out>&&>(*o) =
    std::forward<T>(t); // not required to be equality-preserving const_cast<const iter_reference_t<Out>&&>(*std::forward<Out>(o)) =
    std::forward<T>(t); // not required to be equality-preserving
};
//  Let E be an expression such that decltype((E)) is T, and let o be a dereferenceable object of type Out. Out and T model indirectly_writable<Out, T> only if
//  After evaluating any above assignment expression, o is not required to be dereferenceable.
// — The expressions a++ and a-- shall be prvalues of type I whose values are equal to that of a prior to the evaluation of the expressions. The expression a++ shall modify the value of a by adding 1 to it. The expression a-- shall modify the value of a by subtracting 1 from it.
//  If E is an xvalue (7.2.1), the resulting state of the object it denotes is valid but unspecified (16.4.6.15).
//  [Note 1: The only valid use of an operator* is on the left side of the assignment statement. Assignment through the same value of the indirectly writable type happens only once.
// [Note 2: indirectly_writable has the awkward const_cast expressions to reject iterators with prvalue non-proxy reference types that permit rvalue assignment but do not also permit const rvalue assignment. Consequently, an iterator type I that returns std::string by value does not model indirectly_writable<I, std::string>.
// 25.3.4.4 Concept weakly_incrementable [iterator.concept.winc]
//  The weakly_incrementable concept specifies the requirements on types that can be incremented with the pre- and post-increment operators. The increment operations are not required to be equality-preserving, nor is the type required to be equality_comparable.
template<class T>
inline constexpr bool is_integer_like = see_below ;
template<class T>
inline constexpr bool is_signed_integer_like = see_below ;
template<class I>
concept weakly_incrementable =
    movable<I> &&
requires(I i) {
// exposition only // exposition only
    typename iter_difference_t<I>;
    requires is-signed-integer-like<iter_difference_t<I>>;
    {
        ++i
    }
    -> same_as<I&>; // not required to be equality-preserving i++; // not required to be equality-preserving
};
//  A type I is an integer-class type if it is in a set of implementation-defined types that behave as integer types do, as defined below.
// [Note 1: An integer-class type is not necessarily a class type.
//  The range of representable values of an integer-class type is the continuous set of values over which it is defined. For any integer-class type, its range of representable values is either −2N −1 to 2N −1 − 1 (inclusive) for some integer N , in which case it is a signed-integer-class type, or 0 to 2N − 1 (inclusive) for some integer N, in which case it is an unsigned-integer-class type. In both cases, N is called the width of the integer-class type. The width of an integer-class type is greater than that of every integral type of the same signedness.
//  A type I other than cv bool is integer-like if it models integral<I> or if it is an integer-class type. An integer-like type I is signed-integer-like if it models signed_integral<I> or if it is a signed-integer-class type. An integer-like type I is unsigned-integer-like if it models unsigned_integral<I> or if it is an unsigned-integer-class type.
//  For every integer-class type I, let B(I) be a unique hypothetical extended integer type of the same signedness with the same width (6.8.2) as I.
// [Note 2: The corresponding hypothetical specialization numeric_limits<B(I)> meets the requirements on numeric_- limits specializations for integral types (17.3.5). —end note]
// For every integral type J, let B(J) be the same type as J.
//  Expressions of integer-class type are explicitly convertible to any integer-like type, and implicitly convertible to any integer-class type of equal or greater width and the same signedness. Expressions of integral type are both implicitly and explicitly convertible to any integer-class type. Conversions between integral and integer-class types and between two integer-class types do not exit via an exception. The result of such a conversion is the unique value of the destination type that is congruent to the source modulo 2N , where N is the width of the destination type.
//  Let a be an object of integer-class type I, let b be an object of integer-like type I2 such that the expression b is implicitly convertible to I, let x and y be, respectively, objects of type B(I) and B(I2) as described above that represent the same values as a and b, and let c be an lvalue of any integral type.
// — The expressions ++a, --a, and &a shall be expression-equivalent to a += 1, a -= 1, and addressof(a), respectively.
// — For every unary-operator @ other than & for which the expression @x is well-formed, @a shall also be well-formed and have the same value, effects, and value category as @x. If @x has type bool, so too does @a; if @x has type B(I), then @a has type I.
// — For every assignment operator @= for which c @= x is well-formed, c @= a shall also be well-formed and shall have the same value and effects as c @= x. The expression c @= a shall be an lvalue referring to c.
// — For every assignment operator @= for which x @= y is well-formed, a @= b shall also be well-formed and shall have the same effects as x @= y, except that the value that would be stored into x is stored into a. The expression a @= b shall be an lvalue referring to a.
// — For every non-assignment binary operator @ for which x @ y and y @ x are well-formed, a @ b and b @ a shall also be well-formed and shall have the same value, effects, and value category as x @ y and y @ x,respectively. If x @ yory @ xhastypeB(I),thena @ borb @ a,respectively,hastypeI;if x @ yory @ xhastypeB(I2),thena @ borb @ a,respectively,hastypeI2;ifx @ yory @ xhas any other type, then a @ b or b @ a, respectively, has that type.
// — The expressions ++i and i++ have the same domain.
// — If i is incrementable, then both ++i and i++ advance i to the next element. — If i is incrementable, then addressof(++i) is equal to addressof(i).
//  An expression E of integer-class type I is contextually convertible to bool as if by bool(E != I(0)).
//  All integer-class types model regular (18.6) and three_way_comparable<strong_ordering> (17.11.4).
//  A value-initialized object of integer-class type has value 0.
//  For every (possibly cv-qualified) integer-class type I, numeric_limits<I> is specialized such that each static data member m has the same value as numeric_limits<B(I)>::m, and each static member function f returns I(numeric_limits<B(I)>::f()).
//  For any two integer-like types I1 and I2, at least one of which is an integer-class type, common_type_t<I1, I2> denotes an integer-class type whose width is not less than that of I1 or I2. If both I1 and I2 are signed-integer-like types, then common_type_t<I1, I2> is also a signed-integer-like type.
//  is-integer-like <I> is true if and only if I is an integer-like type. is-signed-integer-like <I> is true if and only if I is a signed-integer-like type.
//  Let i be an object of type I. When i is in the domain of both pre- and post-increment, i is said to be incrementable. I models weakly_incrementable<I> only if
//  Recommended practice: The implementaton of an algorithm on a weakly incrementable type should never attempt to pass through the same incrementable value twice; such an algorithm should be a single-pass algorithm.
// [Note 3: For weakly_incrementable types, a equals b does not imply that ++a equals ++b. (Equality does not guarantee the substitution property or referential transparency.) Such algorithms can be used with istreams as the source of the input data through the istream_iterator class template.
// 25.3.4.5 Concept incrementable [iterator.concept.inc]
//  The incrementable concept specifies requirements on types that can be incremented with the pre- and post-increment operators. The increment operations are required to be equality-preserving, and the type is required to be equality_comparable.
// [Note 1: This supersedes the annotations on the increment expressions in the definition of weakly_incrementable.
template<class I>
concept incrementable =
    regular<I> &&
    weakly_incrementable<I> &&
requires(I i) {
    {
        i++
    }
    -> same_as<I>;
};
sentinel_for<S, I> &&
!disable_sized_sentinel_for<remove_cv_t<S>, remove_cv_t<I>> &&
requires(const I& i, const S& s) {
    {
        s - i
    }
    -> same_as<iter_difference_t<I>>;
    {
        i - s
    }
    -> same_as<iter_difference_t<I>>;
};
// Let i be an iterator of type I, and s a sentinel of type S such that [i, s) denotes a range. Let N be the smallest number of applications of ++i necessary to make bool(i == s) be true. S and I model sized_sentinel_for<S, I> only if
// — If N is representable by iter_difference_t<I>, then s - i is well-defined and equals N.
// — If −N is representable by iter_difference_t<I>, then i - s is well-defined and equals −N.
// 2 Let a and b be incrementable objects of type I. I models incrementable only if
// — If bool(a == b) then bool(a++ == b).
// The input_or_output_iterator concept forms the basis of the iterator concept taxonomy; every iterator models input_or_output_iterator. This concept specifies operations for dereferencing and incrementing an iterator. Most algorithms will require additional operations to compare iterators with sentinels (25.3.4.7), to read (25.3.4.9) or write (25.3.4.10) values, or to provide a richer set of iterator movements (25.3.4.11, 25.3.4.12, 25.3.4.13).
template<class I>
concept input_or_output_iterator =
requires(I i) {
    {
        *i
    }
    -> can-reference;
}
&&
weakly_incrementable<I>;
//  [Note 1: Unlike the Cpp17Iterator requirements, the input_or_output_iterator concept does not require copyability.
// 25.3.4.7 Concept sentinel_for [iterator.concept.sentinel]
// The sentinel_for concept specifies the relationship between an input_or_output_iterator type and a semiregular type whose values denote a range.
template<class S, class I>
concept sentinel_for =
// — If bool(a == b) then bool(((void)a++, a) == ++b).
// [Note 2: The requirement that a equals b implies ++a equals ++b (which is not true for weakly incrementable types) allows the use of multi-pass one-directional algorithms with types that model incrementable.
// 25.3.4.6 Concept input_or_output_iterator [iterator.concept.iterator] semiregular<S> && input_or_output_iterator<I> && weakly-equality-comparable-with <S, I>;
// see 18.5.3
// Let s and i be values of type S and I such that [i,s) denotes a range. Types S and I model sentinel_for<S, I> only if
// — i == s is well-defined.
// — If bool(i != s) then i is dereferenceable and [++i, s) denotes a range. — assignable_from<I&, S> is either modeled or not satisfied.
//  The domain of == is not static. Given an iterator i and sentinel s such that [i, s) denotes a range and i != s, i and s are not required to continue to denote a range after incrementing any other iterator equal to i. Consequently, i == s is no longer required to be well-defined.
// 25.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]
//  The sized_sentinel_for concept specifies requirements on an input_or_output_iterator type I and a corresponding sentinel_for<I> that allow the use of the - operator to compute the distance between them in constant time.
    template<class S, class I>
concept sized_sentinel_for =
    template<class S, class I>
inline constexpr bool disable_sized_sentinel_for = false;
// Remarks: Pursuant to 16.4.5.2.1, users may specialize disable_sized_sentinel_for for cv-unqualified non-array object types S and I if S and/or I is a program-defined type. Such specializations shall be usable in constant expressions (7.7) and have type const bool.
// [Note 1: disable_sized_sentinel_for allows use of sentinels and iterators with the library that satisfy but do not in fact model sized_sentinel_for.
// [Example 1: The sized_sentinel_for concept is modeled by pairs of random_access_iterators (25.3.4.13) and by counted iterators and their sentinels (25.5.6.1).
// 25.3.4.9 Concept input_iterator [iterator.concept.input]
//  The input_iterator concept defines requirements for a type whose referenced values can be read (from th requirement for indirectly_readable (25.3.4.2)) and which can be both pre- and post-incremented.
// [Note 1: Unlike the Cpp17InputIterator requirements (25.3.5.3), the input_iterator concept does not need equality comparison since iterators are typically compared to sentinels.
template<class I>
concept input_iterator =
    input_or_output_iterator<I> && indirectly_readable<I> &&
    requires { typename ITER_CONCEPT(I); } && derived_from<ITER_CONCEPT(I), input_iterator_tag>;
// 25.3.4.10 Concept output_iterator [iterator.concept.output]
//  The output_iterator concept defines requirements for a type that can be used to write values (from the requirement for indirectly_writable (25.3.4.3)) and which can be both pre- and post-incremented. [Note 1: Output iterators are not required to model equality_comparable. —end note]
template<class I, class T>
concept output_iterator =
    input_or_output_iterator<I> &&
    indirectly_writable<I, T> &&
requires(I i, T&& t) {
    *i++ = std::forward<T>(t);
// not required to be equality-preserving
};
//  Let E be an expression such that decltype((E)) is T, and let i be a dereferenceable object of type I. I and T model output_iterator<I, T> only if *i++ = E; has effects equivalent to:
*i = E;
++i;
//  Recommended practice: The implementation of an algorithm on output iterators should never attempt to pass through the same iterator twice; such an algorithm should be a single-pass algorithm.
25.3.4.11 Concept forward_iterator [iterator.concept.forward]
//  The forward_iterator concept adds copyability, equality comparison, and the multi-pass guarantee, specified below.
template<class I>
concept forward_iterator =
    input_iterator<I> &&
    derived_from<ITER_CONCEPT(I), forward_iterator_tag> && incrementable<I> &&
    sentinel_for<I, I>;
//  The domain of == for forward iterators is that of iterators over the same underlying sequence. However, value-initialized iterators of the same type may be compared and shall compare equal to other value-initialized iterators of the same type.
// [Note 1: Value-initialized iterators behave as if they refer past the end of the same empty sequence.
// Pointers and references obtained from a forward iterator into a range [i, s) shall remain valid while [i, s) continues to denote a range.
//  Two dereferenceable iterators a and b of type X offer the multi-pass guarantee if:
// — a == bimplies++a == ++band
// — the expression ((void)[](X x){++x;}(a), *a) is equivalent to the expression *a.
// — If a and b are decrementable, then all of the following are true:
// — addressof(--a) == addressof(a)
// — bool(a-- == b)
// — after evaluating both a-- and --b, bool(a == b) is still true // — bool(++(--a) == b)
// — If a and b are incrementable, then bool(--(++a) == b).
// 25.3.4.13 Concept random_access_iterator [iterator.concept.random.access]
// — (a += n)isequaltob.
// — addressof(a += n) is equal to addressof(a).
// — (a + n)isequalto(a += n).
// — For any two positive values x and y of type D, if (a + D(x + y)) is valid, then (a + D(x + y)) is equal to ((a + x) + y).

//  [Note 2: The requirement that a == b implies ++a == ++b and the removal of the restrictions on the number of assignments through a mutable iterator (which applies to output iterators) allow the use of multi-pass one-directional algorithms with forward iterators.
// 25.3.4.12 Concept bidirectional_iterator [iterator.concept.bidir]
//  The bidirectional_iterator concept adds the ability to move an iterator backward as well as forward.
template<class I>
concept bidirectional_iterator =
    forward_iterator<I> &&
derived_from<ITER_CONCEPT(I), bidirectional_iterator_tag> && requires(I i) {
    {
        --i
    }
    -> same_as<I&>;
    {
        i--
    }
    -> same_as<I>;
};
//  A bidirectional iterator r is decrementable if and only if there exists some q such that ++q == r. Decrementable iterators r shall be in the domain of the expressions --r and r--.
//  Let a and b be equal objects of type I. I models bidirectional_iterator only if:
// The random_access_iterator concept adds support for constant-time advancement with +=, +, -=, and -, as well as the computation of distance in constant time with -. Random access iterators also support array notation via subscripting.
template<class I>
concept random_access_iterator =
    bidirectional_iterator<I> &&
    derived_from<ITER_CONCEPT(I), random_access_iterator_tag> && totally_ordered<I> &&
    sized_sentinel_for<I, I> &&
requires(I i, const I j, const iter_difference_t<I> n) {
    {
        i += n
    }
    -> same_as<I&>;
    {
        j+ n
    }
    ->same_as<I>;
    {
        n+ j
    }
    ->same_as<I>;
    {
        i -= n
    }
    -> same_as<I&>;
    {
        j- n
    }
    ->same_as<I>;
    {
        j[n]
    }
    -> same_as<iter_reference_t<I>>;
};
//  Let a and b be valid iterators of type I such that b is reachable from a after n applications of ++a, let D be iter_difference_t<I>, and let n denote a value of type D. I models random_access_iterator only if
// — (a +
// — If (a
// D(0)) is equal to a.
// + D(n - 1))isvalid,then(a + n)isequalto[](I c){ return ++c; }(a + D(n - 1)).
// — (b += D(-n)) is equal to a.
// — (b -= n)isequaltoa.
// — addressof(b -= n) is equal to addressof(b).
// — (b - n)isequalto(b -= n).
// — If b is dereferenceable, then a[n] is valid and is equal to *b. — bool(a <= b) is true.
// 25.3.4.14 Concept contiguous_iterator
// The contiguous_iterator concept provides a guarantee that the denoted elements are stored contiguously in memory.
template<class I>
concept contiguous_iterator =
    random_access_iterator<I> &&
derived_from<ITER_CONCEPT(I), contiguous_iterator_tag> && is_lvalue_reference_v<iter_reference_t<I>> && same_as<iter_value_t<I>, remove_cvref_t<iter_reference_t<I>>> && requires(const I& i) {
    {
        to_address(i)
    }
    -> same_as<add_pointer_t<iter_reference_t<I>>>;
};
// Let a and b be dereferenceable iterators and c be a non-dereferenceable iterator of type I such that b is reachable from a and c is reachable from b, and let D be iter_difference_t<I>. The type I models contiguous_iterator only if
// — to_address(a) == addressof(*a),
// — to_address(b) == to_address(a) + D(b - a),
// — to_address(c) == to_address(a) + D(c - a),
// — ranges::iter_move(a) has the same type, value category, and effects as std::move(*a), and — if ranges::iter_swap(a, b) is well-formed, it has effects equivalent to ranges::swap(*a, *b).
// 25.3.5 C++17 iterator requirements [iterator.cpp17]
// 25.3.5.1 General [iterator.cpp17.general]
// In the following sections, a and b denote values of type X or const X, difference_type and reference refer to the types iterator_traits<X>::difference_type and iterator_traits<X>::reference, respectively, n denotes a value of difference_type, u, tmp, and m denote identifiers, r denotes a value of X&, t denotes a value of value type T, o denotes a value of some type that is writable to the output iterator.
// [Note 1: For an iterator type X there must be an instantiation of iterator_traits<X> (25.3.2.3).
//  25.3.5.2 Cpp17Iterator [iterator.iterators]
// The Cpp17Iterator requirements form the basis of the iterator taxonomy; every iterator meets the Cpp17- Iterator requirements. This set of requirements specifies operations for dereferencing and incrementing an iterator. Most algorithms will require additional operations to read (25.3.5.3) or write (25.3.5.4) values, or to provide a richer set of iterator movements (25.3.5.5, 25.3.5.6, 25.3.5.7).
// A type X meets the Cpp17Iterator requirements if:
// — X meets the Cpp17CopyConstructible, Cpp17CopyAssignable, and Cpp17Destructible requirements (16.4.4.2) and lvalues of type X are swappable (16.4.4.3), and
// — iterator_traits<X>::difference_type is a signed integer type or void, and — the expressions in Table 82 are valid and have the indicated semantics.
// 25.3.5.3 Input iterators [input.iterators]
// A class or pointer type X meets the requirements of an input iterator for the value type T if X meets the Cpp17Iterator (25.3.5.2) and Cpp17EqualityComparable (Table 27) requirements and the expressions in Table 83 are valid and have the indicated semantics.
// In Table 83, the term the domain of == is used in the ordinary mathematical sense to denote the set of values over which == is (required to be) defined. This set can change over time. Each algorithm places additional
// requirements on the domain of == for the iterator values it uses. These requirements can be inferred from the uses that algorithm makes of == and !=.
// [Example 1: The call find(a,b,x) is defined only if the value of a has the property p defined as follows: b has property p and a value i has property p if (*i==x) or if (*i!=x and ++i has property p).
//   Expression Return type Operational Assertion/note semantics pre-/post-condition    *r unspecified Preconditions: r is dereferenceable.
++r X&
//    Expression Return type Operational Assertion/note semantics pre-/post-condition    a != b contextually !(a == b) Preconditions: (a, b) is in the convertible to domain of ==.
bool
//   *a reference, convertible to T
// Preconditions: a is dereferenceable.
// The expression
(void)*a, *a is equivalent to *a.
// If a == band(a,b)isinthe domain of == then *a is equivalent to *b.
a->m (*a).m
// Preconditions: a is dereferenceable.
++r X&
// Preconditions: r is dereferenceable. Postconditions: r is dereferenceable or r is past-the-end; any copies of the previous value of r are no longer required to be dereferenceable nor to be in the domain of ==.
(void)r++ equivalent to (void)++r
*r++ convertible to T {
    T tmp = *r;
    ++r;
    return tmp;
}
//  Recommended practice: The implementation of an algorithm on input iterators should never attempt to pass through the same iterator twice; such an algorithm should be a single pass algorithm.
// — X meets the Cpp17InputIterator requirements (25.3.5.3),
// — X meets the Cpp17DefaultConstructible requirements (16.4.4.2),
// — if X is a mutable iterator, reference is a reference to T; if X is a constant iterator, reference is a reference to const T,
// — the expressions in Table 85 are valid and have the indicated semantics, and
// — objects of type X offer the multi-pass guarantee, described below.
// [Note 1: For input iterators, a == b does not imply ++a == ++b. (Equality does not guarantee the substitution property or referential transparency.) Value type T is not required to be a Cpp17CopyAssignable type (Table 33). Such an algorithm can be used with istreams as the source of the input data through the istream_iterator class template.
// 25.3.5.4 Output iterators [output.iterators]
//  A class or pointer type X meets the requirements of an output iterator if X meets the Cpp17Iterator requirements (25.3.5.2) and the expressions in Table 84 are valid and have the indicated semantics.
//   Expression Return type Operational Assertion/note semantics pre-/post-condition  *r = o result is not
// Remarks: After this used operation r is not required to be dereferenceable. Postconditions: r is incrementable.
++r X&
// addressof(r) == addressof(++r).
// Remarks: After this operation r is not required to be dereferenceable. Postconditions: r is incrementable.
r++ convertible to {
    X tmp = r;
    const X& ++r;
    return tmp;
}
// Remarks: After this operation r is not required to be dereferenceable. Postconditions: r is incrementable.
*r++ = o result is not Remarks:
       After this
// used operation r is not required to be dereferenceable. Postconditions: r is incrementable.
//  Recommended practice: The implementation of an algorithm on output iterators should never attempt to pass through the same iterator twice; such an algorithm should be a single-pass algorithm.
// [Note 1: The only valid use of an operator* is on the left side of the assignment statement. Assignment through the same value of the iterator happens only once. Equality and inequality are not necessarily defined.
// 25.3.5.5 Forward iterators [forward.iterators]
//  A class or pointer type X meets the requirements of a forward iterator if
//  The domain of == for forward iterators is that of iterators over the same underlying sequence. However, value-initialized iterators may be compared and shall compare equal to other value-initialized iterators of the same type.
// [Note 1: Value-initialized iterators behave as if they refer past the end of the same empty sequence. —end note]
//  Two dereferenceable iterators a and b of type X offer the multi-pass guarantee if:
// — a == bimplies++a == ++band
// — X is a pointer type or the expression (void)++X(a), *a is equivalent to the expression *a.
//  [Note 2: The requirement that a == b implies ++a == ++b (which is not true for input and output iterators) and the removal of the restrictions on the number of the assignments through a mutable iterator (which applies to output iterators) allows the use of multi-pass one-directional algorithms with forward iterators.
//  If a and b are equal, then either a and b are both dereferenceable or else neither is dereferenceable.
//  If a and b are both dereferenceable, then a == b if and only if *a and *b are bound to the same object.
// 25.3.5.6 Bidirectional iterators [bidirectional.iterators]
//  A class or pointer type X meets the requirements of a bidirectional iterator if, in addition to meeting the Cpp17ForwardIterator requirements, the following expressions are valid as shown in Table 86.
//    Expression Return type Operational Assertion/note semantics pre-/post-condition
       r++ convertible to { X tmp = r;
                            const X& ++r;
                            return tmp;
                          }
       *r++ reference
       Expression Return type Operational Assertion/note semantics pre-/post-condition
       --r X&
// Preconditions: there exists s such that r == ++s.
// Postconditions: r is dereferenceable.
       --(++r) == r.
       --r == --s implies r == s.
       addressof(r) == addressof(--r).
       r-- convertible to {
           X tmp = r;
           const X& --r;
           return tmp;
       }
       *r-- reference
// [Note 1 : Bidirectional iterators allow algorithms to move iterators backward as well as forward.
// 25.3.5.7 Random access iterators [random.access.iterators]
//  A class or pointer type X meets the requirements of a random access iterator if, in addition to meeting the Cpp17BidirectionalIterator requirements, the following expressions are valid as shown in Table 87. requirements (in addition to Cpp17BidirectionalIterator)
//    Expression Return type Operational Assertion/note semantics pre-/post-condition
       r += n X&
{   difference_type m = n;
    if (m >= 0)
        while (m--)
            ++r;
    else
        while (m++)
            --r;
    return r;
}
a + n X { X tmp = a; a + n == n + a. n + a return tmp += n; }
r -= n X& return r += -n;
Preconditions:
the absolute value of n is in the range of
representable values of difference_type.
a - n X { X tmp = a; return tmp -= n; }
b - a difference_- return n type
                          Preconditions:
                          there exists a value n of type difference_type such that a + n == b.
                          b == a + (b - a).
                          a[n] convertible to *(a + n) reference
                          a < b contextually Effects:
                          Equivalent to:
                          return < is a total ordering relation convertible to b - a > 0;
bool
a > b contextually b < a > is a total ordering relation convertible to opposite to <.
bool
a >= b contextually !(a < b) convertible to
bool
a <= b contextually !(a > b) convertible to
bool.
// 25.3.6 Indirect callable requirements [indirectcallable]
// 25.3.6.1 General [indirectcallable.general]
// There are several concepts that group requirements of algorithms that take callable objects (22.10.3) as arguments.
// 25.3.6.2 Indirect callables [indirectcallable.indirectinvocable]
//  The indirect callable concepts are used to constrain those algorithms that accept callable objects (22.10.3) as arguments.
namespace std {
template<class F, class I>
concept indirectly_unary_invocable =
    indirectly_readable<I> &&
    copy_constructible<F> &&
    invocable<F&, iter_value_t<I>&> &&
    invocable<F&, iter_reference_t<I>> &&
    invocable<F&, iter_common_reference_t<I>> &&
    common_reference_with<
    invoke_result_t<F&, iter_value_t<I>&>,
    invoke_result_t<F&, iter_reference_t<I>>>;
template<class F, class I>
concept indirectly_regular_unary_invocable =
    indirectly_readable<I> &&
    copy_constructible<F> &&
    regular_invocable<F&, iter_value_t<I>&> &&
    regular_invocable<F&, iter_reference_t<I>> &&
    regular_invocable<F&, iter_common_reference_t<I>> &&
    common_reference_with<
    invoke_result_t<F&, iter_value_t<I>&>,
    invoke_result_t<F&, iter_reference_t<I>>>;
template<class F, class I>
concept indirect_unary_predicate =
    indirectly_readable<I> &&
    copy_constructible<F> &&
    predicate<F&, iter_value_t<I>&> &&
    predicate<F&, iter_reference_t<I>> &&
    predicate<F&, iter_common_reference_t<I>>;
template<class F, class I1, class I2>
concept indirect_binary_predicate =
    indirectly_readable<I1> && indirectly_readable<I2> &&
    copy_constructible<F> &&
    predicate<F&, iter_value_t<I1>&, iter_value_t<I2>&> &&
    predicate<F&, iter_value_t<I1>&, iter_reference_t<I2>> &&
    predicate<F&, iter_reference_t<I1>, iter_value_t<I2>&> &&
    predicate<F&, iter_reference_t<I1>, iter_reference_t<I2>> &&
    predicate<F&, iter_common_reference_t<I1>, iter_common_reference_t<I2>>;
template<class F, class I1, class I2 = I1>
concept indirect_equivalence_relation =
    indirectly_readable<I1> && indirectly_readable<I2> &&
    copy_constructible<F> &&
    equivalence_relation<F&, iter_value_t<I1>&, iter_value_t<I2>&> &&
    equivalence_relation<F&, iter_value_t<I1>&, iter_reference_t<I2>> &&
    equivalence_relation<F&, iter_reference_t<I1>, iter_value_t<I2>&> &&
    equivalence_relation<F&, iter_reference_t<I1>, iter_reference_t<I2>> &&
    equivalence_relation<F&, iter_common_reference_t<I1>, iter_common_reference_t<I2>>;
template<class F, class I1, class I2 = I1>
concept indirect_strict_weak_order =
    indirectly_readable<I1> && indirectly_readable<I2> &&
    copy_constructible<F> &&
    strict_weak_order<F&, iter_value_t<I1>&, iter_value_t<I2>&> &&
    strict_weak_order<F&, iter_value_t<I1>&, iter_reference_t<I2>> &&
    strict_weak_order<F&, iter_reference_t<I1>, iter_value_t<I2>&> &&
    strict_weak_order<F&, iter_reference_t<I1>, iter_reference_t<I2>> &&
    strict_weak_order<F&, iter_common_reference_t<I1>, iter_common_reference_t<I2>>;
}
// 25.3.6.3 Class template projected [projected]
//  Class template projected is used to constrain algorithms that accept callable objects and projections (3.45). It combines a indirectly_readable type I and a callable object type Proj into a new indirectly_readable type whose reference type is the result of applying Proj to the iter_reference_t of I.
namespace std {
template<indirectly_readable I, indirectly_regular_unary_invocable<I> Proj>
struct projected {
    using value_type = remove_cvref_t<indirect_result_t<Proj&, I>>;
    indirect_result_t<Proj&, I> operator*() const; // not defined };
    template<weakly_incrementable I, class Proj>
    struct incrementable_traits<projected<I, Proj>> {
        using difference_type = iter_difference_t<I>;
    };
}
// 25.3.7 Common algorithm requirements [alg.req]
// 25.3.7.1 General [alg.req.general]
//  There are several additional iterator concepts that are commonly applied to families of algorithms. These group together iterator requirements of algorithm families. There are three relational concepts that spec- ify how element values are transferred between indirectly_readable and indirectly_writable types: indirectly_movable, indirectly_copyable, and indirectly_swappable. There are three relational con- cepts for rearrangements: permutable, mergeable, and sortable. There is one relational concept for comparing values from different sequences: indirectly_comparable.
//  [Note 1: The ranges::less function object type used in the concepts below imposes constraints on the concepts’ arguments in addition to those that appear in the concepts’ bodies (22.10.9).
// 25.3.7.2 Concept indirectly_movable [alg.req.ind.move]
//  The indirectly_movable concept specifies the relationship between a indirectly_readable type and a indirectly_writable type between which values may be moved.
template<class In, class Out>
concept indirectly_movable =
    indirectly_readable<In> &&
    indirectly_writable<Out, iter_rvalue_reference_t<In>>;
//  The indirectly_movable_storable concept augments indirectly_movable with additional requirements enabling the transfer to be performed through an intermediate object of the indirectly_readable type’s value type.
template<class In, class Out>
concept indirectly_movable_storable =
    indirectly_movable<In, Out> &&
    indirectly_writable<Out, iter_value_t<In>> &&
    movable<iter_value_t<In>> &&
    constructible_from<iter_value_t<In>, iter_rvalue_reference_t<In>> &&
    assignable_from<iter_value_t<In>&, iter_rvalue_reference_t<In>>;
//  Let i be a dereferenceable value of type In. In and Out model indirectly_movable_storable<In, Out> only if after the initialization of the object obj in
iter_value_t<In> obj(ranges::iter_move(i));
// obj is equal to the value previously denoted by *i. If iter_rvalue_reference_t<In> is an rvalue reference type, the resulting state of the value denoted by *i is valid but unspecified (16.4.6.15).
// 25.3.7.3 Concept indirectly_copyable [alg.req.ind.copy]
//  The indirectly_copyable concept specifies the relationship between a indirectly_readable type and a indirectly_writable type between which values may be copied.
template<class In, class Out>
concept indirectly_copyable =
    indirectly_readable<In> &&
    indirectly_writable<Out, iter_reference_t<In>>;
//  The indirectly_copyable_storable concept augments indirectly_copyable with additional require- ments enabling the transfer to be performed through an intermediate object of the indirectly_readable type’s value type. It also requires the capability to make copies of values.
template<class In, class Out>
concept indirectly_copyable_storable =
    indirectly_copyable<In, Out> &&
    indirectly_writable<Out, iter_value_t<In>&> &&
    indirectly_writable<Out, const iter_value_t<In>&> &&
    indirectly_writable<Out, iter_value_t<In>&&> &&
    indirectly_writable<Out, const iter_value_t<In>&&> &&
    copyable<iter_value_t<In>> &&
    constructible_from<iter_value_t<In>, iter_reference_t<In>> &&
    assignable_from<iter_value_t<In>&, iter_reference_t<In>>;
//  Let i be a dereferenceable value of type In. In and Out model indirectly_copyable_storable<In, Out> only if after the initialization of the object obj in
iter_value_t<In> obj(*i);
// obj is equal to the value previously denoted by *i. If iter_reference_t<In> is an rvalue reference type, the resulting state of the value denoted by *i is valid but unspecified (16.4.6.15).
// 25.3.7.4 Concept indirectly_swappable [alg.req.ind.swap]
//  The indirectly_swappable concept specifies a swappable relationship between the values referenced by two indirectly_readable types.
template<class I1, class I2 = I1>
concept indirectly_swappable =
    indirectly_readable<I1> && indirectly_readable<I2> &&
requires(const I1 i1, const I2 i2) {
    ranges::iter_swap(i1, i1);
    ranges::iter_swap(i2, i2);
    ranges::iter_swap(i1, i2);
    ranges::iter_swap(i2, i1);
};
// 25.3.7.5 Concept indirectly_comparable [alg.req.ind.cmp]
//  The indirectly_comparable concept specifies the common requirements of algorithms that compare values from two different sequences.
template<class I1, class I2, class R, class P1 = identity,
         class P2 = identity>
concept indirectly_comparable =
    indirect_binary_predicate<R, projected<I1, P1>, projected<I2, P2>>;
// 25.3.7.6 Concept permutable [alg.req.permutable]
//  The permutable concept specifies the common requirements of algorithms that reorder elements in place bymoving or swapping them.
template<class I>
concept permutable =
    forward_iterator<I> &&
    indirectly_movable_storable<I, I> &&
    indirectly_swappable<I, I>;
// 25.3.7.7 Concept mergeable [alg.req.mergeable]
//  The mergeable concept specifies the requirements of algorithms that merge sorted sequences into an output sequence by copying elements.
template<class I1, class I2, class Out, class R = ranges::less,
         class P1 = identity, class P2 = identity>
concept mergeable =
    input_iterator<I1> &&
    input_iterator<I2> &&
    weakly_incrementable<Out> &&
    indirectly_copyable<I1, Out> &&
    indirectly_copyable<I2, Out> &&
    indirect_strict_weak_order<R, projected<I1, P1>, projected<I2, P2>>;
// 25.3.7.8 Concept sortable [alg.req.sortable] 1 The sortable concept specifies the common requirements of algorithms that permute sequences into ordered sequences (e.g., sort).
template<class I, class R = ranges::less, class P = identity>
concept sortable =
    permutable<I> &&
    indirect_strict_weak_order<R, projected<I, P>>;
int main() {
    cout  <<  n4910 << endl;
    return EXIT_SUCCESS;
}

編纂・実行結果(compile and go)

bash
$ clang++ p974.cpp -std=03 -o p974l -I. -Wall
In file included from p974.cpp:10:
In file included from ./N4910.h:11:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/atomic:38:
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/c++0x_warning.h:32:2: error: This file requires compiler and library support for the ISO C++ 2011 standard. This support must be enabled with the -std=c++11 or -std=gnu++11 compiler options.
#error This file requires compiler and library support \
 ^
p974.cpp:42:1: error: unknown type name 'constexpr'
constexpr functions.
^
p974.cpp:42:20: error: expected ';' after top level declarator
constexpr functions.
                   ^
                   ;
p974.cpp:83:1: error: unknown type name 'requires'
requires is_object_v<T> struct cond_value_type<T> {
^
p974.cpp:83:10: error: no variable template matches partial specialization
requires is_object_v<T> struct cond_value_type<T> {
         ^
p974.cpp:83:24: error: expected ';' at end of declaration
requires is_object_v<T> struct cond_value_type<T> {
                       ^
                       ;
p974.cpp:83:48: error: use of undeclared identifier 'T'
requires is_object_v<T> struct cond_value_type<T> {
                                               ^
p974.cpp:83:32: error: explicit specialization of undeclared template struct 'cond_value_type'
requires is_object_v<T> struct cond_value_type<T> {
                               ^              ~~~
p974.cpp:84:22: warning: alias declarations are a C++11 extension [-Wc++11-extensions]
  using value_type = remove_cv_t<T>;
                     ^
p974.cpp:84:34: error: use of undeclared identifier 'T'
  using value_type = remove_cv_t<T>;
                                 ^
p974.cpp:88:1: error: unknown type name 'concept'
concept has_member_value_type = requires { typename T::value_type; };
^
p974.cpp:88:9: warning: variable templates are a C++14 extension [-Wc++14-extensions]
concept has_member_value_type = requires { typename T::value_type; };
        ^
p974.cpp:88:33: error: use of undeclared identifier 'requires'
concept has_member_value_type = requires { typename T::value_type; };
                                ^
p974.cpp:88:41: error: expected ';' at end of declaration
concept has_member_value_type = requires { typename T::value_type; };
                                        ^
                                        ;
p974.cpp:88:42: error: expected unqualified-id
concept has_member_value_type = requires { typename T::value_type; };
                                         ^
p974.cpp:90:1: error: unknown type name 'concept'
concept has_member_element_type = requires { typename T::element_type; };
^
p974.cpp:90:9: warning: variable templates are a C++14 extension [-Wc++14-extensions]
concept has_member_element_type = requires { typename T::element_type; };
        ^
p974.cpp:90:35: error: use of undeclared identifier 'requires'
concept has_member_element_type = requires { typename T::element_type; };
                                  ^
p974.cpp:90:43: error: expected ';' at end of declaration
concept has_member_element_type = requires { typename T::element_type; };
                                          ^
                                          ;
p974.cpp:90:44: error: expected unqualified-id
concept has_member_element_type = requires { typename T::element_type; };
                                           ^
p974.cpp:94:3: error: unknown template name 'cond_value_type'
: cond_value_type<T> { };
  ^
p974.cpp:96:3: error: unknown type name 'requires'
  requires is_array_v<I>
  ^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
3 warnings and 20 errors generated.
$ clang++ p974.cpp -std=2b -o p974l -I. -Wall
p974.cpp:42:11: error: unknown type name 'functions'
constexpr functions.
          ^
p974.cpp:42:20: error: cannot use dot operator on a type
constexpr functions.
                   ^
p974.cpp:50:31: error: redefinition of 'incrementable_traits'
       template<class> struct incrementable_traits { };
                              ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/iterator_concepts.h:149:29: note: previous definition is here
  template<typename> struct incrementable_traits { };
                            ^
p974.cpp:53:15: error: redefinition of 'incrementable_traits<T *>'
       struct incrementable_traits<T*> {
              ^~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/iterator_concepts.h:152:12: note: previous definition is here
    struct incrementable_traits<_Tp*>
           ^
p974.cpp:57:15: error: redefinition of 'incrementable_traits<const I>'
       struct incrementable_traits<const I>
              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/iterator_concepts.h:156:12: note: previous definition is here
    struct incrementable_traits<const _Iter>
           ^
p974.cpp:62:15: error: redefinition of 'incrementable_traits<T>'
       struct incrementable_traits<T> {
              ^~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/iterator_concepts.h:160:12: note: previous definition is here
    struct incrementable_traits<_Tp>
           ^
p974.cpp:72:27: error: unknown type name 'see_below'
using iter_difference_t = see_below;
                          ^
p974.cpp:78:2: error: expected unqualified-id
(2.2)
 ^
p974.cpp:78:2: error: expected ')'
p974.cpp:78:1: note: to match this '('
(2.2)
^
p974.cpp:83:32: error: no template named 'cond_value_type'; did you mean 'std::__detail::__cond_value_type'?
requires is_object_v<T> struct cond_value_type<T> {
                               ^~~~~~~~~~~~~~~
                               std::__detail::__cond_value_type
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/iterator_concepts.h:218:31: note: 'std::__detail::__cond_value_type' declared here
    template<typename> struct __cond_value_type { };
                              ^
p974.cpp:83:32: error: redefinition of '__cond_value_type<T>'
requires is_object_v<T> struct cond_value_type<T> {
                               ^~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/iterator_concepts.h:221:14: note: previous definition is here
      struct __cond_value_type<_Tp>
             ^
p974.cpp:93:8: error: reference to 'indirectly_readable_traits' is ambiguous
struct indirectly_readable_traits<T*>
       ^
p974.cpp:91:24: note: candidate found by name lookup is 'indirectly_readable_traits'
template<class> struct indirectly_readable_traits { };
                       ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/iterator_concepts.h:225:29: note: candidate found by name lookup is 'std::indirectly_readable_traits'
  template<typename> struct indirectly_readable_traits { };
                            ^
p974.cpp:94:3: error: no template named 'cond_value_type'; did you mean 'std::__detail::__cond_value_type'?
: cond_value_type<T> { };
  ^~~~~~~~~~~~~~~
  std::__detail::__cond_value_type
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/iterator_concepts.h:218:31: note: 'std::__detail::__cond_value_type' declared here
    template<typename> struct __cond_value_type { };
                              ^
p974.cpp:97:8: error: reference to 'indirectly_readable_traits' is ambiguous
struct indirectly_readable_traits<I> {
       ^
p974.cpp:91:24: note: candidate found by name lookup is 'indirectly_readable_traits'
template<class> struct indirectly_readable_traits { };
                       ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/iterator_concepts.h:225:29: note: candidate found by name lookup is 'std::indirectly_readable_traits'
  template<typename> struct indirectly_readable_traits { };
                            ^
p974.cpp:101:8: error: reference to 'indirectly_readable_traits' is ambiguous
struct indirectly_readable_traits<const I>
       ^
p974.cpp:91:24: note: candidate found by name lookup is 'indirectly_readable_traits'
template<class> struct indirectly_readable_traits { };
                       ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/iterator_concepts.h:225:29: note: candidate found by name lookup is 'std::indirectly_readable_traits'
  template<typename> struct indirectly_readable_traits { };
                            ^
p974.cpp:102:5: error: reference to 'indirectly_readable_traits' is ambiguous
  : indirectly_readable_traits<I> { };
    ^
p974.cpp:91:24: note: candidate found by name lookup is 'indirectly_readable_traits'
template<class> struct indirectly_readable_traits { };
                       ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/iterator_concepts.h:225:29: note: candidate found by name lookup is 'std::indirectly_readable_traits'
  template<typename> struct indirectly_readable_traits { };
                            ^
p974.cpp:103:42: error: reference to 'indirectly_readable_traits' is ambiguous
template<has_member_value_type T> struct indirectly_readable_traits<T>
                                         ^
p974.cpp:91:24: note: candidate found by name lookup is 'indirectly_readable_traits'
template<class> struct indirectly_readable_traits { };
                       ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/iterator_concepts.h:225:29: note: candidate found by name lookup is 'std::indirectly_readable_traits'
  template<typename> struct indirectly_readable_traits { };
                            ^
p974.cpp:104:3: error: no template named 'cond_value_type'; did you mean 'std::__detail::__cond_value_type'?
: cond_value_type<typename T::value_type> { };
  ^~~~~~~~~~~~~~~
  std::__detail::__cond_value_type
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/iterator_concepts.h:218:31: note: 'std::__detail::__cond_value_type' declared here
    template<typename> struct __cond_value_type { };
                              ^
p974.cpp:107:44: error: reference to 'indirectly_readable_traits' is ambiguous
template<has_member_element_type T> struct indirectly_readable_traits<T>
                                           ^
p974.cpp:91:24: note: candidate found by name lookup is 'indirectly_readable_traits'
template<class> struct indirectly_readable_traits { };
                       ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/iterator_concepts.h:225:29: note: candidate found by name lookup is 'std::indirectly_readable_traits'
  template<typename> struct indirectly_readable_traits { };
                            ^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
20 errors generated.

$ g++ p974.cpp -std=03 -o p974g -I. -Wall
In file included from /usr/local/include/c++/12.1.0/atomic:38,
                 from N4910.h:11,
                 from p974.cpp:10:
/usr/local/include/c++/12.1.0/bits/c++0x_warning.h:32:2: error: #error This file requires compiler and library support for the ISO C++ 2011 standard. This support must be enabled with the -std=c++11 or -std=gnu++11 compiler options.
   32 | #error This file requires compiler and library support \
      |  ^~~~~
p974.cpp:42:1: warning: identifier 'constexpr' is a keyword in C++11 [-Wc++11-compat]
   42 | constexpr functions.
      | ^~~~~~~~~
p974.cpp:69:48: warning: identifier 'decltype' is a keyword in C++11 [-Wc++11-compat]
   69 |          using difference_type = make_signed_t<decltype(declval<T>() - declval<T>())>;
      |                                                ^~~~~~~~
p974.cpp:244:2: error: too many decimal points in number
  244 | (18.4.9) denoted by its arguments.
      |  ^~~~~~
p974.cpp:248:1: warning: identifier 'noexcept' is a keyword in C++11 [-Wc++11-compat]
  248 | noexcept(noexcept(iter_value_t<X>(iter_move(x))) &&
      | ^~~~~~~~
p974.cpp:426:1: error: too many decimal points in number
  426 | 25.3.4.11 Concept forward_iterator [iterator.concept.forward]
      | ^~~~~~~~~
p974.cpp:42:1: error: 'constexpr' does not name a type
   42 | constexpr functions.
      | ^~~~~~~~~
p974.cpp:42:1: note: C++11 'constexpr' only available with '-std=c++11' or '-std=gnu++11'
p974.cpp:78:2: error: expected unqualified-id before numeric constant
   78 | (2.2)
      |  ^~~
p974.cpp:78:2: error: expected ')' before numeric constant
   78 | (2.2)
      | ~^~~
      |  )
p974.cpp:83:1: error: 'requires' does not name a type
   83 | requires is_object_v<T> struct cond_value_type<T> {
      | ^~~~~~~~
p974.cpp:83:1: note: 'requires' only available with '-std=c++20' or '-fconcepts'
p974.cpp:88:1: error: 'concept' does not name a type; did you mean 'const'?
   88 | concept has_member_value_type = requires { typename T::value_type; };
      | ^~~~~~~
      | const
p974.cpp:88:1: note: 'concept' only available with '-std=c++20' or '-fconcepts'
p974.cpp:90:1: error: 'concept' does not name a type; did you mean 'const'?
   90 | concept has_member_element_type = requires { typename T::element_type; };
      | ^~~~~~~
      | const
p974.cpp:90:1: note: 'concept' only available with '-std=c++20' or '-fconcepts'
p974.cpp:94:18: error: expected template-name before '<' token
   94 | : cond_value_type<T> { };
      |                  ^
p974.cpp:94:18: error: expected '{' before '<' token
p974.cpp:96:3: error: 'requires' does not name a type
   96 |   requires is_array_v<I>
      |   ^~~~~~~~
p974.cpp:96:3: note: 'requires' only available with '-std=c++20' or '-fconcepts'
p974.cpp:103:10: error: 'has_member_value_type' has not been declared
  103 | template<has_member_value_type T> struct indirectly_readable_traits<T>
      |          ^~~~~~~~~~~~~~~~~~~~~
p974.cpp:103:69: error: 'T' was not declared in this scope
  103 | template<has_member_value_type T> struct indirectly_readable_traits<T>
      |                                                                     ^
p974.cpp:103:70: error: template argument 1 is invalid
  103 | template<has_member_value_type T> struct indirectly_readable_traits<T>
      |                                                                      ^
p974.cpp:104:18: error: expected template-name before '<' token
  104 | : cond_value_type<typename T::value_type> { };
      |                  ^
p974.cpp:107:10: error: 'has_member_element_type' has not been declared
  107 | template<has_member_element_type T> struct indirectly_readable_traits<T>
      |          ^~~~~~~~~~~~~~~~~~~~~~~
p974.cpp:107:71: error: 'T' was not declared in this scope
  107 | template<has_member_element_type T> struct indirectly_readable_traits<T>
      |                                                                       ^
p974.cpp:107:72: error: template argument 1 is invalid
  107 | template<has_member_element_type T> struct indirectly_readable_traits<T>
      |                                                                        ^
p974.cpp:108:18: error: expected template-name before '<' token
  108 | : cond_value_type<typename T::element_type> { };
      |                  ^
p974.cpp:109:10: error: 'has_member_value_type' has not been declared
  109 | template<has_member_value_type T> requires has-member_element_type<T>
      |          ^~~~~~~~~~~~~~~~~~~~~
p974.cpp:109:35: error: 'requires' does not name a type
  109 | template<has_member_value_type T> requires has-member_element_type<T>
      |                                   ^~~~~~~~
p974.cpp:109:35: note: 'requires' only available with '-std=c++20' or '-fconcepts'
p974.cpp:111:10: error: 'has_member_value_type' has not been declared
  111 | template<has_member_value_type T> requires has-member_element_type<T> &&
      |          ^~~~~~~~~~~~~~~~~~~~~
p974.cpp:111:35: error: 'requires' does not name a type
  111 | template<has_member_value_type T> requires has-member_element_type<T> &&
      |                                   ^~~~~~~~
p974.cpp:111:35: note: 'requires' only available with '-std=c++20' or '-fconcepts'
p974.cpp:114:66: error: expected unqualified-id before 'using'
  114 | : cond_value_type<typename T::value_type> { }; template<class T> using iter_value_t = see_below;
      |                                                                  ^~~~~
p974.cpp:121:22: error: 'I' was not declared in this scope
  121 |      iterator_traits<I>::iterator_category
      |                      ^
p974.cpp:121:23: error: template argument 1 is invalid
  121 |      iterator_traits<I>::iterator_category
      |                       ^
p974.cpp:123:6: error: expected initializer before 'iterator_traits'
  123 |      iterator_traits<I>::pointer
      |      ^~~~~~~~~~~~~~~
p974.cpp:135:10: error: expected unqualified-id before '&&' token
  135 |        } && copyable<I>;
      |          ^~
p974.cpp:137:1: error: 'concept' does not name a type; did you mean 'const'?
  137 | concept cpp17-input-iterator =
      | ^~~~~~~
      | const
p974.cpp:137:1: note: 'concept' only available with '-std=c++20' or '-fconcepts'
p974.cpp:150:1: error: 'concept' does not name a type; did you mean 'const'?
  150 | concept cpp17-forward-iterator =
      | ^~~~~~~
      | const
p974.cpp:150:1: note: 'concept' only available with '-std=c++20' or '-fconcepts'
p974.cpp:158:1: error: 'concept' does not name a type; did you mean 'const'?
  158 | concept cpp17-bidirectional-iterator =
      | ^~~~~~~
      | const
p974.cpp:158:1: note: 'concept' only available with '-std=c++20' or '-fconcepts'
p974.cpp:164:1: error: 'concept' does not name a type; did you mean 'const'?
  164 | concept cpp17-random-access-iterator =
      | ^~~~~~~
      | const
p974.cpp:164:1: note: 'concept' only available with '-std=c++20' or '-fconcepts'
p974.cpp:176:7: error: expected nested-name-specifier before 'value_type'
  176 | using value_type = typename I::value_type;
      |       ^~~~~~~~~~
p974.cpp:177:7: error: expected nested-name-specifier before 'difference_type'
  177 | using difference_type = typename I::difference_type;
      |       ^~~~~~~~~~~~~~~
p974.cpp:178:7: error: expected nested-name-specifier before 'pointer'
  178 | using pointer  = see_below ;
      |       ^~~~~~~
p974.cpp:179:7: error: expected nested-name-specifier before 'reference'
  179 | using reference = typename I::reference;
      |       ^~~~~~~~~
p974.cpp:182:7: error: expected nested-name-specifier before 'iterator_category'
  182 | using iterator_category = see_below;
      |       ^~~~~~~~~~~~~~~~~
p974.cpp:183:7: error: expected nested-name-specifier before 'value_type'
  183 | using value_type = typename indirectly_readable_traits<I>::value_type;
      |       ^~~~~~~~~~
p974.cpp:184:7: error: expected nested-name-specifier before 'difference_type'
  184 | using difference_type = typename incrementable_traits<I>::difference_type;
      |       ^~~~~~~~~~~~~~~
p974.cpp:185:7: error: expected nested-name-specifier before 'pointer'
  185 | using pointer  = see_below ;
      |       ^~~~~~~
p974.cpp:186:7: error: expected nested-name-specifier before 'reference'
  186 | using reference  = see_below ;
      |       ^~~~~~~~~
p974.cpp:194:12: error: expected nested-name-specifier before 'iterator_category'
  194 |      using iterator_category = output_iterator_tag;
      |            ^~~~~~~~~~~~~~~~~
p974.cpp:195:7: error: expected nested-name-specifier before 'value_type'
  195 | using value_type = void;
      |       ^~~~~~~~~~
p974.cpp:196:7: error: expected nested-name-specifier before 'difference_type'
  196 | using difference_type = see_below ;
      |       ^~~~~~~~~~~~~~~
p974.cpp:197:7: error: expected nested-name-specifier before 'pointer'
  197 | using pointer = void;
      |       ^~~~~~~
p974.cpp:198:7: error: expected nested-name-specifier before 'reference'
  198 | using reference = void;
      |       ^~~~~~~~~
p974.cpp:205:10: error: 'requires' does not name a type
  205 |          requires is_object_v<T>
      |          ^~~~~~~~
p974.cpp:205:10: note: 'requires' only available with '-std=c++20' or '-fconcepts'
p974.cpp:211:7: error: expected nested-name-specifier before 'value_type'
  211 | using value_type = remove_cv_t<T>;
      |       ^~~~~~~~~~
p974.cpp:212:7: error: expected nested-name-specifier before 'difference_type'
  212 | using difference_type = ptrdiff_t;
      |       ^~~~~~~~~~~~~~~
p974.cpp:213:7: error: expected nested-name-specifier before 'pointer'
  213 | using pointer = T*;
      |       ^~~~~~~
p974.cpp:214:7: error: expected nested-name-specifier before 'reference'
  214 | using reference = T&;
      |       ^~~~~~~~~
p974.cpp:244:2: error: expected unqualified-id before numeric constant
  244 | (18.4.9) denoted by its arguments.
      |  ^~~~~~
p974.cpp:244:2: error: expected ')' before numeric constant
  244 | (18.4.9) denoted by its arguments.
      | ~^~~~~~
      |  )
p974.cpp:251:4: error: 'iter_value_t' does not name a type
  251 |    iter_value_t<X> old_value(iter_move(x));
      |    ^~~~~~~~~~~~
p974.cpp:252:7: error: expected constructor, destructor, or type conversion before '=' token
  252 |    *x = iter_move(y);
      |       ^
p974.cpp:253:4: error: expected unqualified-id before 'return'
  253 |    return old_value;
      |    ^~~~~~
p974.cpp:257:33: warning: defaulted and deleted functions only available with '-std=c++11' or '-std=gnu++11' [-Wc++11-extensions]
  257 |        void iter_swap(I1, I2) = delete;
      |                                 ^~~~~~
p974.cpp:271:14: error: expected nested-name-specifier before 'value_type'
  271 |        using value_type = int;
      |              ^~~~~~~~~~
p974.cpp:272:14: error: expected nested-name-specifier before 'difference_type'
  272 |        using difference_type = int;
      |              ^~~~~~~~~~~~~~~
p974.cpp:284:1: error: 'concept' does not name a type; did you mean 'const'?
  284 | concept indirectly-readable-impl =
      | ^~~~~~~
      | const
p974.cpp:284:1: note: 'concept' only available with '-std=c++20' or '-fconcepts'
p974.cpp:291:12: error: expected unqualified-id before '&&' token
  291 |          } &&
      |            ^~
p974.cpp:296:8: error: 'concept' does not name a type; did you mean 'const'?
  296 |        concept indirectly_readable =
      |        ^~~~~~~
      |        const
p974.cpp:296:8: note: 'concept' only available with '-std=c++20' or '-fconcepts'
p974.cpp:303:8: error: 'concept' does not name a type; did you mean 'const'?
  303 |        concept indirectly_writable =
      |        ^~~~~~~
      |        const
p974.cpp:303:8: note: 'concept' only available with '-std=c++20' or '-fconcepts'
p974.cpp:319:8: error: 'constexpr' does not name a type
  319 | inline constexpr bool is_integer_like = see_below ;
      |        ^~~~~~~~~
p974.cpp:319:8: note: C++11 'constexpr' only available with '-std=c++11' or '-std=gnu++11'
p974.cpp:321:8: error: 'constexpr' does not name a type
  321 | inline constexpr bool is_signed_integer_like = see_below ;
      |        ^~~~~~~~~
p974.cpp:321:8: note: C++11 'constexpr' only available with '-std=c++11' or '-std=gnu++11'
p974.cpp:323:3: error: 'concept' does not name a type; did you mean 'const'?
  323 |   concept weakly_incrementable =
      |   ^~~~~~~
      |   const
p974.cpp:323:3: note: 'concept' only available with '-std=c++20' or '-fconcepts'
p974.cpp:360:8: error: 'concept' does not name a type; did you mean 'const'?
  360 |        concept incrementable =
      |        ^~~~~~~
      |        const
p974.cpp:360:8: note: 'concept' only available with '-std=c++20' or '-fconcepts'
p974.cpp:366:1: error: 'sentinel_for' does not name a type
  366 | sentinel_for<S, I> &&
      | ^~~~~~~~~~~~
p974.cpp:379:10: error: 'concept' does not name a type; did you mean 'const'?
  379 |          concept input_or_output_iterator =
      |          ^~~~~~~
      |          const
p974.cpp:379:10: note: 'concept' only available with '-std=c++20' or '-fconcepts'
p974.cpp:382:14: error: expected unqualified-id before '&&' token
  382 |            } &&
      |              ^~
p974.cpp:388:8: error: 'concept' does not name a type; did you mean 'const'?
  388 |        concept sentinel_for =
      |        ^~~~~~~
      |        const
p974.cpp:388:8: note: 'concept' only available with '-std=c++20' or '-fconcepts'
p974.cpp:410:8: error: 'concept' does not name a type; did you mean 'const'?
  410 |        concept input_iterator =
      |        ^~~~~~~
      |        const
p974.cpp:410:8: note: 'concept' only available with '-std=c++20' or '-fconcepts'
p974.cpp:412:40: error: expected unqualified-id before '&&' token
  412 | requires { typename ITER_CONCEPT(I); } && derived_from<ITER_CONCEPT(I), input_iterator_tag>;
      |                                        ^~
p974.cpp:416:3: error: 'concept' does not name a type; did you mean 'const'?
  416 |   concept output_iterator =
      |   ^~~~~~~
      |   const
p974.cpp:416:3: note: 'concept' only available with '-std=c++20' or '-fconcepts'
p974.cpp:424:4: error: expected constructor, destructor, or type conversion before '=' token
  424 | *i = E; ++i;
      |    ^
p974.cpp:424:9: error: expected unqualified-id before '++' token
  424 | *i = E; ++i;
      |         ^~
p974.cpp:426:1: error: expected unqualified-id before numeric constant
  426 | 25.3.4.11 Concept forward_iterator [iterator.concept.forward]
      | ^~~~~~~~~
p974.cpp:454:8: error: 'concept' does not name a type; did you mean 'const'?
  454 |        concept bidirectional_iterator =
      |        ^~~~~~~
      |        const
p974.cpp:454:8: note: 'concept' only available with '-std=c++20' or '-fconcepts'
p974.cpp:464:8: error: 'concept' does not name a type; did you mean 'const'?
  464 |        concept random_access_iterator =
      |        ^~~~~~~
      |        const
p974.cpp:464:8: note: 'concept' only available with '-std=c++20' or '-fconcepts'
p974.cpp:489:5: error: 'concept' does not name a type; did you mean 'const'?
  489 |     concept contiguous_iterator =
      |     ^~~~~~~
      |     const
p974.cpp:489:5: note: 'concept' only available with '-std=c++20' or '-fconcepts'
p974.cpp:514:4: error: expected unqualified-id before '++' token
  514 |    ++r X&
      |    ^~
p974.cpp:540:4: error: expected unqualified-id before '++' token
  540 |    ++r X&
      |    ^~
p974.cpp:546:6: error: expected constructor, destructor, or type conversion before '++' token
  546 |    *r++ = o result is not Remarks: After this
      |      ^~
p974.cpp:565:6: error: expected constructor, destructor, or type conversion before '++' token
  565 |    *r++ reference
      |      ^~
p974.cpp:575:6: error: expected constructor, destructor, or type conversion before '--' token
  575 |    *r-- reference
      |      ^~
p974.cpp:589:4: error: 'a' does not name a type
  589 |    a + n X { X tmp = a; a + n == n + a. n + a return tmp += n; }
      |    ^
p974.cpp:590:4: error: 'r' does not name a type
  590 |    r -= n X& return r += -n; Preconditions: the absolute value of n is in the range of
      |    ^
p974.cpp:590:43: error: found ':' in nested-name-specifier, expected '::'
  590 |    r -= n X& return r += -n; Preconditions: the absolute value of n is in the range of
      |                                           ^
      |                                           ::
p974.cpp:590:30: error: 'Preconditions' does not name a type
  590 |    r -= n X& return r += -n; Preconditions: the absolute value of n is in the range of
      |                              ^~~~~~~~~~~~~
p974.cpp:593:4: error: 'b' does not name a type
  593 |    b - a difference_- return n type
      |    ^
p974.cpp:599:6: error: expected initializer before '>' token
  599 |    a > b contextually b < a > is a total ordering relation convertible to opposite to <.
      |      ^
p974.cpp:669:17: error: 'indirectly_readable' has not been declared
  669 |        template<indirectly_readable I, indirectly_regular_unary_invocable<I> Proj>
      |                 ^~~~~~~~~~~~~~~~~~~
p974.cpp:669:40: error: 'indirectly_regular_unary_invocable' has not been declared
  669 |        template<indirectly_readable I, indirectly_regular_unary_invocable<I> Proj>
      |                                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
p974.cpp:669:74: error: expected '>' before '<' token
  669 |        template<indirectly_readable I, indirectly_regular_unary_invocable<I> Proj>
      |                                                                          ^
p974.cpp:670:15: error: no default argument for '<anonymous>'
  670 |        struct projected {
      |               ^~~~~~~~~
p974.cpp:671:16: error: expected nested-name-specifier before 'value_type'
  671 |          using value_type = remove_cvref_t<indirect_result_t<Proj&, I>>;
      |                ^~~~~~~~~~
p974.cpp:672:1: error: 'indirect_result_t' does not name a type
  672 | indirect_result_t<Proj&, I> operator*() const; // not defined };
      | ^~~~~~~~~~~~~~~~~
p974.cpp:673:12: error: 'weakly_incrementable' has not been declared
  673 |   template<weakly_incrementable I, class Proj>
      |            ^~~~~~~~~~~~~~~~~~~~
p974.cpp:674:10: error: 'incrementable_traits' is not a class template
  674 |   struct incrementable_traits<projected<I, Proj>> {
      |          ^~~~~~~~~~~~~~~~~~~~
p974.cpp:674:48: error: '>>' should be '> >' within a nested template argument list
  674 |   struct incrementable_traits<projected<I, Proj>> {
      |                                                ^~
      |                                                > >
p974.cpp:674:44: error: type/value mismatch at argument 2 in template parameter list for 'template<<declaration error>, <typeprefixerror><anonymous> > struct std::projected'
  674 |   struct incrementable_traits<projected<I, Proj>> {
      |                                            ^~~~
p974.cpp:674:44: note:   expected a constant of type '<type error>', got 'Proj'
p974.cpp:674:48: error: no default argument for 'Proj'
  674 |   struct incrementable_traits<projected<I, Proj>> {
      |                                                ^~
p974.cpp:675:11: error: expected nested-name-specifier before 'difference_type'
  675 |     using difference_type = iter_difference_t<I>;
      |           ^~~~~~~~~~~~~~~
p974.cpp:677:2: error: expected ';' after struct definition
  677 | }
      |  ^
      |  ;
p974.cpp:685:8: error: 'concept' does not name a type
  685 |        concept indirectly_movable =
      |        ^~~~~~~
p974.cpp:685:8: note: 'concept' only available with '-std=c++20' or '-fconcepts'
p974.cpp:690:8: error: 'concept' does not name a type
  690 |        concept indirectly_movable_storable =
      |        ^~~~~~~
p974.cpp:690:8: note: 'concept' only available with '-std=c++20' or '-fconcepts'
p974.cpp:697:6: error: 'iter_value_t' does not name a type
  697 |      iter_value_t<In> obj(ranges::iter_move(i));
      |      ^~~~~~~~~~~~
p974.cpp:702:8: error: 'concept' does not name a type
  702 |        concept indirectly_copyable =
      |        ^~~~~~~
p974.cpp:702:8: note: 'concept' only available with '-std=c++20' or '-fconcepts'
p974.cpp:707:8: error: 'concept' does not name a type
  707 |        concept indirectly_copyable_storable =
      |        ^~~~~~~
p974.cpp:707:8: note: 'concept' only available with '-std=c++20' or '-fconcepts'
p974.cpp:717:6: error: 'iter_value_t' does not name a type
  717 |      iter_value_t<In> obj(*i);
      |      ^~~~~~~~~~~~
p974.cpp:722:8: error: 'concept' does not name a type
  722 |        concept indirectly_swappable =
      |        ^~~~~~~
p974.cpp:722:8: note: 'concept' only available with '-std=c++20' or '-fconcepts'
p974.cpp:732:55: error: 'identity' does not name a type
  732 |      template<class I1, class I2, class R, class P1 = identity,
      |                                                       ^~~~~~~~
p974.cpp:733:26: error: 'identity' does not name a type
  733 |               class P2 = identity>
      |                          ^~~~~~~~
p974.cpp:734:8: error: 'concept' does not name a type
  734 |        concept indirectly_comparable =
      |        ^~~~~~~
p974.cpp:734:8: note: 'concept' only available with '-std=c++20' or '-fconcepts'
p974.cpp:739:8: error: 'concept' does not name a type
  739 |        concept permutable =
      |        ^~~~~~~
p974.cpp:739:8: note: 'concept' only available with '-std=c++20' or '-fconcepts'
p974.cpp:745:56: error: 'ranges' does not name a type
  745 |      template<class I1, class I2, class Out, class R = ranges::less,
      |                                                        ^~~~~~
p974.cpp:745:62: error: expected '>' before '::' token
  745 |      template<class I1, class I2, class Out, class R = ranges::less,
      |                                                              ^~
p974.cpp:747:8: error: 'concept' does not name a type
  747 |        concept mergeable =
      |        ^~~~~~~
p974.cpp:747:8: note: 'concept' only available with '-std=c++20' or '-fconcepts'
p974.cpp:755:34: error: 'ranges' does not name a type
  755 |      template<class I, class R = ranges::less, class P = identity>
      |                                  ^~~~~~
p974.cpp:755:40: error: expected '>' before '::' token
  755 |      template<class I, class R = ranges::less, class P = identity>
      |                                        ^~
p974.cpp:756:8: error: 'concept' does not name a type
  756 |        concept sortable =
      |        ^~~~~~~
p974.cpp:756:8: note: 'concept' only available with '-std=c++20' or '-fconcepts'
p974.cpp:762:2: error: expected '}' at end of input
  762 | }
      |  ^
p974.cpp:668:20: note: to match this '{'
  668 |      namespace std {
      |                    ^

$ g++ p974.cpp -std=2b -o p974g -I. -Wall
p974.cpp:244:2: error: too many decimal points in number
  244 | (18.4.9) denoted by its arguments.
      |  ^~~~~~
p974.cpp:426:1: error: too many decimal points in number
  426 | 25.3.4.11 Concept forward_iterator [iterator.concept.forward]
      | ^~~~~~~~~
p974.cpp:42:11: error: 'functions' does not name a type
   42 | constexpr functions.
      |           ^~~~~~~~~
p974.cpp:78:2: error: expected unqualified-id before numeric constant
   78 | (2.2)
      |  ^~~
p974.cpp:78:2: error: expected ')' before numeric constant
   78 | (2.2)
      | ~^~~
      |  )
p974.cpp:83:32: error: 'cond_value_type' is not a class template
   83 | requires is_object_v<T> struct cond_value_type<T> {
      |                                ^~~~~~~~~~~~~~~
p974.cpp:93:8: error: 'indirectly_readable_traits' is not a class template
   93 | struct indirectly_readable_traits<T*>
      |        ^~~~~~~~~~~~~~~~~~~~~~~~~~
p974.cpp:93:8: error: redefinition of 'struct indirectly_readable_traits< <template-parameter-1-1> >'
p974.cpp:91:24: note: previous definition of 'struct indirectly_readable_traits< <template-parameter-1-1> >'
   91 | template<class> struct indirectly_readable_traits { };
      |                        ^~~~~~~~~~~~~~~~~~~~~~~~~~
p974.cpp:97:8: error: 'indirectly_readable_traits' is not a class template
   97 | struct indirectly_readable_traits<I> {
      |        ^~~~~~~~~~~~~~~~~~~~~~~~~~
p974.cpp:97:36: error: redeclaration 'template<class> struct indirectly_readable_traits' with different constraints
   97 | struct indirectly_readable_traits<I> {
      |                                    ^
p974.cpp:91:24: note: original declaration appeared here
   91 | template<class> struct indirectly_readable_traits { };
      |                        ^~~~~~~~~~~~~~~~~~~~~~~~~~
p974.cpp:101:8: error: 'indirectly_readable_traits' is not a class template
  101 | struct indirectly_readable_traits<const I>
      |        ^~~~~~~~~~~~~~~~~~~~~~~~~~
p974.cpp:101:8: error: redefinition of 'struct indirectly_readable_traits< <template-parameter-1-1> >'
p974.cpp:91:24: note: previous definition of 'struct indirectly_readable_traits< <template-parameter-1-1> >'
   91 | template<class> struct indirectly_readable_traits { };
      |                        ^~~~~~~~~~~~~~~~~~~~~~~~~~
p974.cpp:103:42: error: 'indirectly_readable_traits' is not a class template
  103 | template<has_member_value_type T> struct indirectly_readable_traits<T>
      |                                          ^~~~~~~~~~~~~~~~~~~~~~~~~~
p974.cpp:103:10: error: declaration of template parameter 'class T' with different constraints
  103 | template<has_member_value_type T> struct indirectly_readable_traits<T>
      |          ^~~~~~~~~~~~~~~~~~~~~
p974.cpp:91:10: note: original declaration appeared here
   91 | template<class> struct indirectly_readable_traits { };
      |          ^~~~~
p974.cpp:107:44: error: 'indirectly_readable_traits' is not a class template
  107 | template<has_member_element_type T> struct indirectly_readable_traits<T>
      |                                            ^~~~~~~~~~~~~~~~~~~~~~~~~~
p974.cpp:107:10: error: declaration of template parameter 'class T' with different constraints
  107 | template<has_member_element_type T> struct indirectly_readable_traits<T>
      |          ^~~~~~~~~~~~~~~~~~~~~~~
p974.cpp:91:10: note: original declaration appeared here
   91 | template<class> struct indirectly_readable_traits { };
      |          ^~~~~
p974.cpp:109:44: error: 'has' was not declared in this scope
  109 | template<has_member_value_type T> requires has-member_element_type<T>
      |                                            ^~~
p974.cpp:109:48: error: 'member_element_type' was not declared in this scope; did you mean 'has_member_element_type'?
  109 | template<has_member_value_type T> requires has-member_element_type<T>
      |                                                ^~~~~~~~~~~~~~~~~~~
      |                                                has_member_element_type
p974.cpp:109:35: error: expression must be enclosed in parentheses
  109 | template<has_member_value_type T> requires has-member_element_type<T>
      |                                   ^~~~~~~~
p974.cpp:109:44: error: 'has' does not name a type
  109 | template<has_member_value_type T> requires has-member_element_type<T>
      |                                            ^~~
p974.cpp:111:44: error: 'has' was not declared in this scope
  111 | template<has_member_value_type T> requires has-member_element_type<T> &&
      |                                            ^~~
p974.cpp:111:48: error: 'member_element_type' was not declared in this scope; did you mean 'has_member_element_type'?
  111 | template<has_member_value_type T> requires has-member_element_type<T> &&
      |                                                ^~~~~~~~~~~~~~~~~~~
      |                                                has_member_element_type
p974.cpp:112:17: error: label 'same_as' referenced outside of any function
  112 |                 same_as<remove_cv_t<typename T::element_type>, remove_cv_t<typename T::value_type>>
      |                 ^~~~~~~
p974.cpp:111:35: error: expression must be enclosed in parentheses
  111 | template<has_member_value_type T> requires has-member_element_type<T> &&
      |                                   ^~~~~~~~
p974.cpp:111:44: error: 'has' does not name a type
  111 | template<has_member_value_type T> requires has-member_element_type<T> &&
      |                                            ^~~
p974.cpp:114:87: error: 'see_below' does not name a type
  114 | : cond_value_type<typename T::value_type> { }; template<class T> using iter_value_t = see_below;
      |                                                                                       ^~~~~~~~~
p974.cpp:121:22: error: 'I' was not declared in this scope
  121 |      iterator_traits<I>::iterator_category
      |                      ^
p974.cpp:121:23: error: template argument 1 is invalid
  121 |      iterator_traits<I>::iterator_category
      |                       ^
p974.cpp:123:6: error: expected initializer before 'iterator_traits'
  123 |      iterator_traits<I>::pointer
      |      ^~~~~~~~~~~~~~~
p974.cpp:135:22: error: 'I' was not declared in this scope
  135 |        } && copyable<I>;
      |                      ^
p974.cpp:135:13: error: template argument 1 is invalid
  135 |        } && copyable<I>;
      |             ^~~~~~~~~~~
p974.cpp:137:14: error: expected '=' before '-' token
  137 | concept cpp17-input-iterator =
      |              ^
p974.cpp:150:14: error: expected '=' before '-' token
  150 | concept cpp17-forward-iterator =
      |              ^
p974.cpp:158:14: error: expected '=' before '-' token
  158 | concept cpp17-bidirectional-iterator =
      |              ^
p974.cpp:164:14: error: expected '=' before '-' token
  164 | concept cpp17-random-access-iterator =
      |              ^
p974.cpp:176:29: error: 'I' has not been declared
  176 | using value_type = typename I::value_type;
      |                             ^
p974.cpp:177:34: error: 'I' has not been declared
  177 | using difference_type = typename I::difference_type;
      |                                  ^
p974.cpp:178:18: error: 'see_below' does not name a type
  178 | using pointer  = see_below ;
      |                  ^~~~~~~~~
p974.cpp:179:28: error: 'I' has not been declared
  179 | using reference = typename I::reference;
      |                            ^
p974.cpp:182:27: error: 'see_below' does not name a type
  182 | using iterator_category = see_below;
      |                           ^~~~~~~~~
p974.cpp:183:29: error: expected nested-name-specifier before 'indirectly_readable_traits'
  183 | using value_type = typename indirectly_readable_traits<I>::value_type;
      |                             ^~~~~~~~~~~~~~~~~~~~~~~~~~
p974.cpp:183:56: error: 'I' was not declared in this scope
  183 | using value_type = typename indirectly_readable_traits<I>::value_type;
      |                                                        ^
p974.cpp:183:56: error: 'I' was not declared in this scope
p974.cpp:183:56: error: 'I' was not declared in this scope
p974.cpp:183:56: error: 'I' was not declared in this scope
p974.cpp:184:55: error: 'I' was not declared in this scope
  184 | using difference_type = typename incrementable_traits<I>::difference_type;
      |                                                       ^
p974.cpp:184:56: error: template argument 1 is invalid
  184 | using difference_type = typename incrementable_traits<I>::difference_type;
      |                                                        ^
p974.cpp:185:18: error: 'see_below' does not name a type
  185 | using pointer  = see_below ;
      |                  ^~~~~~~~~
p974.cpp:186:20: error: 'see_below' does not name a type
  186 | using reference  = see_below ;
      |                    ^~~~~~~~~
p974.cpp:196:25: error: 'see_below' does not name a type
  196 | using difference_type = see_below ;
      |                         ^~~~~~~~~
p974.cpp:206:15: error: redefinition of 'struct std::iterator_traits<_Tp*>'
  206 |        struct iterator_traits<T*> {
      |               ^~~~~~~~~~~~~~~~~~~
In file included from /usr/local/include/c++/12.1.0/bits/stl_construct.h:61,
                 from /usr/local/include/c++/12.1.0/bits/char_traits.h:46,
                 from /usr/local/include/c++/12.1.0/ios:40,
                 from /usr/local/include/c++/12.1.0/ostream:38,
                 from /usr/local/include/c++/12.1.0/iostream:39,
                 from N4910.h:2,
                 from p974.cpp:10:
/usr/local/include/c++/12.1.0/bits/stl_iterator_base_types.h:198:12: note: previous definition of 'struct std::iterator_traits<_Tp*>'
  198 |     struct iterator_traits<_Tp*>
      |            ^~~~~~~~~~~~~~~~~~~~~
p974.cpp:211:32: error: 'T' was not declared in this scope
  211 | using value_type = remove_cv_t<T>;
      |                                ^
p974.cpp:211:33: error: template argument 1 is invalid
  211 | using value_type = remove_cv_t<T>;
      |                                 ^
p974.cpp:213:17: error: 'T' does not name a type
  213 | using pointer = T*;
      |                 ^
p974.cpp:214:19: error: 'T' does not name a type
  214 | using reference = T&;
      |                   ^
p974.cpp:244:2: error: expected unqualified-id before numeric constant
  244 | (18.4.9) denoted by its arguments.
      |  ^~~~~~
p974.cpp:244:2: error: expected ')' before numeric constant
  244 | (18.4.9) denoted by its arguments.
      | ~^~~~~~
      |  )
p974.cpp:251:17: error: 'X' was not declared in this scope
  251 |    iter_value_t<X> old_value(iter_move(x));
      |                 ^
p974.cpp:251:18: error: template argument 1 is invalid
  251 |    iter_value_t<X> old_value(iter_move(x));
      |                  ^
p974.cpp:251:40: error: 'x' was not declared in this scope
  251 |    iter_value_t<X> old_value(iter_move(x));
      |                                        ^
p974.cpp:252:7: error: expected constructor, destructor, or type conversion before '=' token
  252 |    *x = iter_move(y);
      |       ^
p974.cpp:253:4: error: expected unqualified-id before 'return'
  253 |    return old_value;
      |    ^~~~~~
p974.cpp:284:19: error: expected '=' before '-' token
  284 | concept indirectly-readable-impl =
      |                   ^
p974.cpp:291:11: error: expected ';' before '&&' token
  291 |          } &&
      |           ^~~
      |           ;
p974.cpp:297:1: error: 'indirectly' was not declared in this scope
  297 | indirectly-readable-impl<remove_cvref_t<In>>;
      | ^~~~~~~~~~
p974.cpp:297:12: error: 'readable' was not declared in this scope
  297 | indirectly-readable-impl<remove_cvref_t<In>>;
      |            ^~~~~~~~
p974.cpp:297:21: error: 'impl' was not declared in this scope
  297 | indirectly-readable-impl<remove_cvref_t<In>>;
      |                     ^~~~
p974.cpp:297:43: error: expected primary-expression before '>' token
  297 | indirectly-readable-impl<remove_cvref_t<In>>;
      |                                           ^~
p974.cpp:297:45: error: expected primary-expression before ';' token
  297 | indirectly-readable-impl<remove_cvref_t<In>>;
      |                                             ^
p974.cpp:319:41: error: 'see_below' was not declared in this scope
  319 | inline constexpr bool is_integer_like = see_below ;
      |                                         ^~~~~~~~~
p974.cpp:321:48: error: 'see_below' was not declared in this scope
  321 | inline constexpr bool is_signed_integer_like = see_below ;
      |                                                ^~~~~~~~~
p974.cpp:328:10: error: 'is' was not declared in this scope; did you mean 'i'?
  328 | requires is-signed-integer-like<iter_difference_t<I>>;
      |          ^~
      |          i
p974.cpp:328:13: error: expected primary-expression before 'signed'
  328 | requires is-signed-integer-like<iter_difference_t<I>>;
      |             ^~~~~~
p974.cpp:362:10: error: reference to 'weakly_incrementable' is ambiguous
  362 |          weakly_incrementable<I> &&
      |          ^~~~~~~~~~~~~~~~~~~~
In file included from /usr/local/include/c++/12.1.0/bits/stl_iterator_base_types.h:71:
/usr/local/include/c++/12.1.0/bits/iterator_concepts.h:600:13: note: candidates are: 'template<class _Iter> concept std::weakly_incrementable'
  600 |     concept weakly_incrementable = movable<_Iter>
      |             ^~~~~~~~~~~~~~~~~~~~
p974.cpp:323:11: note:                 'template<class I> concept weakly_incrementable'
  323 |   concept weakly_incrementable =
      |           ^~~~~~~~~~~~~~~~~~~~
p974.cpp:362:32: error: expected primary-expression before '>' token
  362 |          weakly_incrementable<I> &&
      |                                ^
p974.cpp:363:10: error: expected identifier before 'requires'
  363 |          requires(I i) {
      |          ^~~~~~~~
p974.cpp:366:14: error: 'S' was not declared in this scope
  366 | sentinel_for<S, I> &&
      |              ^
p974.cpp:366:1: error: template argument 1 is invalid
  366 | sentinel_for<S, I> &&
      | ^~~~~~~~~~~~~~~~~~
p974.cpp:366:1: error: '<expression error>' does not name a type
p974.cpp:381:11: error: 'can' does not name a type
  381 | { *i } -> can-reference;
      |           ^~~
p974.cpp:381:24: error: expected primary-expression before ';' token
  381 | { *i } -> can-reference;
      |                        ^
p974.cpp:383:12: error: reference to 'weakly_incrementable' is ambiguous
  383 |            weakly_incrementable<I>;
      |            ^~~~~~~~~~~~~~~~~~~~
/usr/local/include/c++/12.1.0/bits/iterator_concepts.h:600:13: note: candidates are: 'template<class _Iter> concept std::weakly_incrementable'
  600 |     concept weakly_incrementable = movable<_Iter>
      |             ^~~~~~~~~~~~~~~~~~~~
p974.cpp:323:11: note:                 'template<class I> concept weakly_incrementable'
  323 |   concept weakly_incrementable =
      |           ^~~~~~~~~~~~~~~~~~~~
p974.cpp:383:34: error: expected primary-expression before '>' token
  383 |            weakly_incrementable<I>;
      |                                  ^
p974.cpp:383:35: error: expected primary-expression before ';' token
  383 |            weakly_incrementable<I>;
      |                                   ^
p974.cpp:399:4: error: expected primary-expression before 'template'
  399 |    template<class S, class I>
      |    ^~~~~~~~
p974.cpp:411:1: error: reference to 'input_or_output_iterator' is ambiguous
  411 | input_or_output_iterator<I> && indirectly_readable<I> &&
      | ^~~~~~~~~~~~~~~~~~~~~~~~
/usr/local/include/c++/12.1.0/bits/iterator_concepts.h:614:13: note: candidates are: 'template<class _Iter> concept std::input_or_output_iterator'
  614 |     concept input_or_output_iterator
      |             ^~~~~~~~~~~~~~~~~~~~~~~~
p974.cpp:379:18: note:                 'template<class I> concept input_or_output_iterator'
  379 |          concept input_or_output_iterator =
      |                  ^~~~~~~~~~~~~~~~~~~~~~~~
p974.cpp:411:27: error: expected primary-expression before '>' token
  411 | input_or_output_iterator<I> && indirectly_readable<I> &&
      |                           ^
p974.cpp:411:32: error: label 'indirectly_readable' referenced outside of any function
  411 | input_or_output_iterator<I> && indirectly_readable<I> &&
      |                                ^~~~~~~~~~~~~~~~~~~
p974.cpp:411:53: error: expected primary-expression before '>' token
  411 | input_or_output_iterator<I> && indirectly_readable<I> &&
      |                                                     ^
p974.cpp:412:1: error: expected identifier before 'requires'
  412 | requires { typename ITER_CONCEPT(I); } && derived_from<ITER_CONCEPT(I), input_iterator_tag>;
      | ^~~~~~~~
p974.cpp:412:39: error: expected ';' before '&&' token
  412 | requires { typename ITER_CONCEPT(I); } && derived_from<ITER_CONCEPT(I), input_iterator_tag>;
      |                                       ^~~
      |                                       ;
p974.cpp:417:5: error: reference to 'input_or_output_iterator' is ambiguous
  417 |     input_or_output_iterator<I> &&
      |     ^~~~~~~~~~~~~~~~~~~~~~~~
/usr/local/include/c++/12.1.0/bits/iterator_concepts.h:614:13: note: candidates are: 'template<class _Iter> concept std::input_or_output_iterator'
  614 |     concept input_or_output_iterator
      |             ^~~~~~~~~~~~~~~~~~~~~~~~
p974.cpp:379:18: note:                 'template<class I> concept input_or_output_iterator'
  379 |          concept input_or_output_iterator =
      |                  ^~~~~~~~~~~~~~~~~~~~~~~~
p974.cpp:417:31: error: expected primary-expression before '>' token
  417 |     input_or_output_iterator<I> &&
      |                               ^
p974.cpp:418:5: error: label 'indirectly_writable' referenced outside of any function
  418 |     indirectly_writable<I, T> &&
      |     ^~~~~~~~~~~~~~~~~~~
p974.cpp:418:26: error: expected primary-expression before ',' token
  418 |     indirectly_writable<I, T> &&
      |                          ^
p974.cpp:424:4: error: expected constructor, destructor, or type conversion before '=' token
  424 | *i = E; ++i;
      |    ^
p974.cpp:424:9: error: expected unqualified-id before '++' token
  424 | *i = E; ++i;
      |         ^~
p974.cpp:426:1: error: expected unqualified-id before numeric constant
  426 | 25.3.4.11 Concept forward_iterator [iterator.concept.forward]
      | ^~~~~~~~~
p974.cpp:456:14: error: there are no arguments to 'ITER_CONCEPT' that depend on a template parameter, so a declaration of 'ITER_CONCEPT' must be available [-fpermissive]
  456 | derived_from<ITER_CONCEPT(I), bidirectional_iterator_tag> && requires(I i) {
      |              ^~~~~~~~~~~~
p974.cpp:456:14: note: (if you use '-fpermissive', G++ will accept your code, but allowing the use of an undeclared name is deprecated)
p974.cpp:456:1: error: parse error in template argument list
  456 | derived_from<ITER_CONCEPT(I), bidirectional_iterator_tag> && requires(I i) {
      | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
p974.cpp:456:1: error: template argument 1 is invalid
p974.cpp:465:1: error: reference to 'bidirectional_iterator' is ambiguous
  465 | bidirectional_iterator<I> &&
      | ^~~~~~~~~~~~~~~~~~~~~~
/usr/local/include/c++/12.1.0/bits/iterator_concepts.h:652:13: note: candidates are: 'template<class _Iter> concept std::bidirectional_iterator'
  652 |     concept bidirectional_iterator = forward_iterator<_Iter>
      |             ^~~~~~~~~~~~~~~~~~~~~~
p974.cpp:454:16: note:                 'template<class I> concept bidirectional_iterator'
  454 |        concept bidirectional_iterator =
      |                ^~~~~~~~~~~~~~~~~~~~~~
p974.cpp:465:25: error: expected primary-expression before '>' token
  465 | bidirectional_iterator<I> &&
      |                         ^
p974.cpp:466:1: error: label 'derived_from' referenced outside of any function
  466 | derived_from<ITER_CONCEPT(I), random_access_iterator_tag> && totally_ordered<I> &&
      | ^~~~~~~~~~~~
p974.cpp:466:28: error: expected primary-expression before ')' token
  466 | derived_from<ITER_CONCEPT(I), random_access_iterator_tag> && totally_ordered<I> &&
      |                            ^
p974.cpp:466:14: error: there are no arguments to 'ITER_CONCEPT' that depend on a template parameter, so a declaration of 'ITER_CONCEPT' must be available [-fpermissive]
  466 | derived_from<ITER_CONCEPT(I), random_access_iterator_tag> && totally_ordered<I> &&
      |              ^~~~~~~~~~~~
p974.cpp:490:1: error: reference to 'random_access_iterator' is ambiguous
  490 | random_access_iterator<I> &&
      | ^~~~~~~~~~~~~~~~~~~~~~
/usr/local/include/c++/12.1.0/bits/iterator_concepts.h:662:13: note: candidates are: 'template<class _Iter> concept std::random_access_iterator'
  662 |     concept random_access_iterator = bidirectional_iterator<_Iter>
      |             ^~~~~~~~~~~~~~~~~~~~~~
p974.cpp:464:16: note:                 'template<class I> concept random_access_iterator'
  464 |        concept random_access_iterator =
      |                ^~~~~~~~~~~~~~~~~~~~~~
p974.cpp:490:25: error: expected primary-expression before '>' token
  490 | random_access_iterator<I> &&
      |                         ^
p974.cpp:491:1: error: label 'derived_from' referenced outside of any function
  491 | derived_from<ITER_CONCEPT(I), contiguous_iterator_tag> && is_lvalue_reference_v<iter_reference_t<I>> && same_as<iter_value_t<I>, remove_cvref_t<iter_reference_t<I>>> && requires(const I& i) {
      | ^~~~~~~~~~~~
p974.cpp:491:28: error: expected primary-expression before ')' token
  491 | derived_from<ITER_CONCEPT(I), contiguous_iterator_tag> && is_lvalue_reference_v<iter_reference_t<I>> && same_as<iter_value_t<I>, remove_cvref_t<iter_reference_t<I>>> && requires(const I& i) {
      |                            ^
p974.cpp:491:14: error: there are no arguments to 'ITER_CONCEPT' that depend on a template parameter, so a declaration of 'ITER_CONCEPT' must be available [-fpermissive]
  491 | derived_from<ITER_CONCEPT(I), contiguous_iterator_tag> && is_lvalue_reference_v<iter_reference_t<I>> && same_as<iter_value_t<I>, remove_cvref_t<iter_reference_t<I>>> && requires(const I& i) {
      |              ^~~~~~~~~~~~
p974.cpp:514:4: error: expected unqualified-id before '++' token
  514 |    ++r X&
      |    ^~
p974.cpp:540:4: error: expected unqualified-id before '++' token
  540 |    ++r X&
      |    ^~
p974.cpp:546:6: error: expected constructor, destructor, or type conversion before '++' token
  546 |    *r++ = o result is not Remarks: After this
      |      ^~
p974.cpp:565:6: error: expected constructor, destructor, or type conversion before '++' token
  565 |    *r++ reference
      |      ^~
p974.cpp:575:6: error: expected constructor, destructor, or type conversion before '--' token
  575 |    *r-- reference
      |      ^~
p974.cpp:589:4: error: 'a' does not name a type
  589 |    a + n X { X tmp = a; a + n == n + a. n + a return tmp += n; }
      |    ^
p974.cpp:590:4: error: 'r' does not name a type
  590 |    r -= n X& return r += -n; Preconditions: the absolute value of n is in the range of
      |    ^
p974.cpp:590:43: error: found ':' in nested-name-specifier, expected '::'
  590 |    r -= n X& return r += -n; Preconditions: the absolute value of n is in the range of
      |                                           ^
      |                                           ::
p974.cpp:590:30: error: 'Preconditions' does not name a type
  590 |    r -= n X& return r += -n; Preconditions: the absolute value of n is in the range of
      |                              ^~~~~~~~~~~~~
p974.cpp:593:4: error: 'b' does not name a type
  593 |    b - a difference_- return n type
      |    ^
p974.cpp:599:6: error: expected initializer before '>' token
  599 |    a > b contextually b < a > is a total ordering relation convertible to opposite to <.
      |      ^
p974.cpp:670:15: error: redefinition of 'struct std::projected<_Iter, _Proj>'
  670 |        struct projected {
      |               ^~~~~~~~~
/usr/local/include/c++/12.1.0/bits/iterator_concepts.h:757:12: note: previous definition of 'struct std::projected<_Iter, _Proj>'
  757 |     struct projected
      |            ^~~~~~~~~
p974.cpp:690:16: error: redefinition of 'template<class In, class Out> concept std::indirectly_movable_storable'
  690 |        concept indirectly_movable_storable =
      |                ^~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/local/include/c++/12.1.0/bits/iterator_concepts.h:777:13: note: 'template<class _In, class _Out> concept std::indirectly_movable_storable' previously declared here
  777 |     concept indirectly_movable_storable = indirectly_movable<_In, _Out>
      |             ^~~~~~~~~~~~~~~~~~~~~~~~~~~
p974.cpp:697:19: error: 'In' was not declared in this scope; did you mean 'yn'?
  697 |      iter_value_t<In> obj(ranges::iter_move(i));
      |                   ^~
      |                   yn
p974.cpp:697:21: error: template argument 1 is invalid
  697 |      iter_value_t<In> obj(ranges::iter_move(i));
      |                     ^
p974.cpp:697:45: error: 'i' was not declared in this scope
  697 |      iter_value_t<In> obj(ranges::iter_move(i));
      |                                             ^
p974.cpp:702:16: error: redefinition of 'template<class In, class Out> concept std::indirectly_copyable'
  702 |        concept indirectly_copyable =
      |                ^~~~~~~~~~~~~~~~~~~
/usr/local/include/c++/12.1.0/bits/iterator_concepts.h:785:13: note: 'template<class _In, class _Out> concept std::indirectly_copyable' previously declared here
  785 |     concept indirectly_copyable = indirectly_readable<_In>
      |             ^~~~~~~~~~~~~~~~~~~
p974.cpp:707:16: error: redefinition of 'template<class In, class Out> concept std::indirectly_copyable_storable'
  707 |        concept indirectly_copyable_storable =
      |                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/local/include/c++/12.1.0/bits/iterator_concepts.h:789:13: note: 'template<class _In, class _Out> concept std::indirectly_copyable_storable' previously declared here
  789 |     concept indirectly_copyable_storable = indirectly_copyable<_In, _Out>
      |             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
p974.cpp:717:19: error: 'In' was not declared in this scope; did you mean 'yn'?
  717 |      iter_value_t<In> obj(*i);
      |                   ^~
      |                   yn
p974.cpp:717:21: error: template argument 1 is invalid
  717 |      iter_value_t<In> obj(*i);
      |                     ^
p974.cpp:717:23: error: redefinition of 'int std::obj'
  717 |      iter_value_t<In> obj(*i);
      |                       ^~~
p974.cpp:697:23: note: 'int std::obj' previously defined here
  697 |      iter_value_t<In> obj(ranges::iter_move(i));
      |                       ^~~
p974.cpp:717:28: error: 'i' was not declared in this scope
  717 |      iter_value_t<In> obj(*i);
      |                            ^
p974.cpp:722:16: error: redefinition of 'template<class I1, class I2> concept std::indirectly_swappable'
  722 |        concept indirectly_swappable =
      |                ^~~~~~~~~~~~~~~~~~~~
/usr/local/include/c++/12.1.0/bits/iterator_concepts.h:878:13: note: 'template<class _I1, class _I2> concept std::indirectly_swappable' previously declared here
  878 |     concept indirectly_swappable
      |             ^~~~~~~~~~~~~~~~~~~~
p974.cpp:734:16: error: redefinition of 'template<class I1, class I2, class R, class P1, class P2> concept std::indirectly_comparable'
  734 |        concept indirectly_comparable =
      |                ^~~~~~~~~~~~~~~~~~~~~
/usr/local/include/c++/12.1.0/bits/iterator_concepts.h:891:13: note: 'template<class _I1, class _I2, class _Rel, class _P1, class _P2> concept std::indirectly_comparable' previously declared here
  891 |     concept indirectly_comparable
      |             ^~~~~~~~~~~~~~~~~~~~~
p974.cpp:739:16: error: redefinition of 'template<class I> concept std::permutable'
  739 |        concept permutable =
      |                ^~~~~~~~~~
/usr/local/include/c++/12.1.0/bits/iterator_concepts.h:897:13: note: 'template<class _Iter> concept std::permutable' previously declared here
  897 |     concept permutable = forward_iterator<_Iter>
      |             ^~~~~~~~~~
p974.cpp:747:16: error: redefinition of 'template<class I1, class I2, class Out, class R, class P1, class P2> concept std::mergeable'
  747 |        concept mergeable =
      |                ^~~~~~~~~
/usr/local/include/c++/12.1.0/bits/iterator_concepts.h:905:13: note: 'template<class _I1, class _I2, class _Out, class _Rel, class _P1, class _P2> concept std::mergeable' previously declared here
  905 |     concept mergeable = input_iterator<_I1> && input_iterator<_I2>
      |             ^~~~~~~~~
p974.cpp:756:16: error: redefinition of 'template<class I, class R, class P> concept std::sortable'
  756 |        concept sortable =
      |                ^~~~~~~~
/usr/local/include/c++/12.1.0/bits/iterator_concepts.h:914:13: note: 'template<class _Iter, class _Rel, class _Proj> concept std::sortable' previously declared here
  914 |     concept sortable = permutable<_Iter>
      |             ^~~~~~~~
p974.cpp:762:2: error: expected '}' at end of input
  762 | }
      |  ^
p974.cpp:668:20: note: to match this '{'
  668 |      namespace std {
      |                    ^

検討事項(agenda)

コンパイルエラーを取るか、コンパイルエラーの理由を解説する。

参考資料(reference)

関連する自己参照以外は、こちらの先頭に移転。

C言語(C++)に対する誤解、曲解、無理解、爽快。

#include "N4910.h"

C++N4910資料の改善点

dockerにclang

docker gnu(gcc/g++) and llvm(clang/clang++)

コンパイル用shell script C版(clangとgcc)とC++版(clang++とg++)

C++N4910:2022 tag follower 300人超えました。ありがとうございます。

astyle 使ってみた

DoCAP(ドゥーキャップ)って何ですか?

小川メソッド 覚え(書きかけ)

<この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。>

文書履歴(document history)

ver. 0.01 初稿  20220808

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?