File: mergeable.compile.pass.cpp

package info (click to toggle)
llvm-toolchain-16 1%3A16.0.6-15~deb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 1,634,792 kB
  • sloc: cpp: 6,179,261; ansic: 1,216,205; asm: 741,319; python: 196,614; objc: 75,325; f90: 49,640; lisp: 32,396; pascal: 12,286; sh: 9,394; perl: 7,442; ml: 5,494; awk: 3,523; makefile: 2,723; javascript: 1,206; xml: 886; fortran: 581; cs: 573
file content (127 lines) | stat: -rw-r--r-- 5,625 bytes parent folder | download | duplicates (14)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17

// template<class I1, class I2, class Out,
//     class R = ranges::less, class P1 = identity, class P2 = identity>
//   concept mergeable = see below;                           // since C++20

#include <iterator>

#include <functional>

#include "test_iterators.h"
#include "test_macros.h"

using CompDefault = std::ranges::less;
using CompInt = bool(*)(int, int);
using ProjDefault = std::identity;

using Input = cpp20_input_iterator<int*>;
static_assert( std::input_iterator<Input>);
using InputLong = cpp20_input_iterator<long*>;
static_assert( std::input_iterator<InputLong>);

using Output = cpp17_output_iterator<int*>;
static_assert( std::weakly_incrementable<Output>);

static_assert( std::indirectly_copyable<Input, Output>);
static_assert( std::indirectly_copyable<InputLong, Output>);
static_assert( std::indirect_strict_weak_order<CompDefault, Input, Input>);
static_assert( std::indirect_strict_weak_order<CompInt, Input, Input>);
static_assert( std::indirect_strict_weak_order<CompDefault, Input, InputLong>);
static_assert( std::indirect_strict_weak_order<CompInt, Input, InputLong>);

// All requirements satisfied.
static_assert( std::mergeable<Input, Input, Output>);
static_assert( std::mergeable<Input, Input, Output, CompInt>);
static_assert( std::mergeable<Input, Input, Output, CompInt, ProjDefault>);

// Non-default projections.
struct Foo {};
using ProjFooToInt = int(*)(Foo);
using ProjFooToLong = long(*)(Foo);
static_assert( std::indirect_strict_weak_order<CompDefault,
    std::projected<Foo*, ProjFooToInt>, std::projected<Foo*, ProjFooToLong>>);
static_assert( std::mergeable<Foo*, Foo*, Foo*, CompDefault, ProjFooToInt, ProjFooToLong>);
static_assert( std::indirect_strict_weak_order<CompInt,
    std::projected<Foo*, ProjFooToInt>, std::projected<Foo*, ProjFooToLong>>);
static_assert( std::mergeable<Foo*, Foo*, Foo*, CompInt, ProjFooToInt, ProjFooToLong>);

// I1 or I2 is not an input iterator.
static_assert(!std::input_iterator<Output>);
static_assert(!std::mergeable<Output, Input, Output>);
static_assert(!std::mergeable<Input, Output, Output>);

// O is not weakly incrementable.
struct NotWeaklyIncrementable {
  int& operator*() const;
};

static_assert(!std::weakly_incrementable<NotWeaklyIncrementable>);
static_assert( std::indirectly_copyable<Input, NotWeaklyIncrementable>);
static_assert( std::indirect_strict_weak_order<CompDefault, Input, Input>);
static_assert(!std::mergeable<Input, Input, NotWeaklyIncrementable>);

// I1 or I2 is not indirectly copyable into O.
struct AssignableOnlyFromInt {
  AssignableOnlyFromInt& operator=(int);
  template <class T>
  AssignableOnlyFromInt& operator=(T) = delete;
};
using OutputOnlyInt = cpp17_output_iterator<AssignableOnlyFromInt*>;
static_assert( std::weakly_incrementable<OutputOnlyInt>);

static_assert( std::indirectly_copyable<Input, OutputOnlyInt>);
static_assert(!std::indirectly_copyable<InputLong, OutputOnlyInt>);
static_assert( std::indirect_strict_weak_order<CompDefault, Input, InputLong>);
static_assert( std::mergeable<Input, Input, OutputOnlyInt>);
static_assert(!std::mergeable<Input, InputLong, OutputOnlyInt>);
static_assert(!std::mergeable<InputLong, Input, OutputOnlyInt>);

// No indirect strict weak order between I1 and I2 (bad comparison functor).
using GoodComp = bool(*)(int, int);
static_assert( std::indirect_strict_weak_order<GoodComp, Input, Input>);
static_assert( std::mergeable<Input, Input, Output, GoodComp>);
using BadComp = bool(*)(int*, int*);
static_assert(!std::indirect_strict_weak_order<BadComp, Input, Input>);
static_assert(!std::mergeable<Input, Input, Output, BadComp>);

// No indirect strict weak order between I1 and I2 (bad projection).
using ToInt = int(*)(int);
using ToPtr = int*(*)(int);
static_assert( std::mergeable<Input, Input, Output, GoodComp, std::identity, std::identity>);
static_assert( std::mergeable<Input, Input, Output, GoodComp, ToInt, ToInt>);
static_assert(!std::mergeable<Input, Input, Output, GoodComp, ToPtr, ToInt>);
static_assert(!std::mergeable<Input, Input, Output, GoodComp, ToInt, ToPtr>);
static_assert(!std::mergeable<Input, Input, Output, bool(*)(int*, int), ToPtr, ToInt>);
static_assert(!std::mergeable<Input, Input, Output, bool(*)(int, int*), ToInt, ToPtr>);

// A projection that only supports non-const references and has a non-const `operator()` still has to work.
struct ProjectionOnlyMutable {
  int operator()(int&);
  int operator()(int&&) const = delete;
};
static_assert( std::mergeable<Input, Input, Output, CompDefault, ProjectionOnlyMutable, ProjectionOnlyMutable>);

// The output is weakly incrementable but not an output iterator.
struct WeaklyIncrementable {
  using value_type = int;
  using difference_type = int;

  int& operator*() const;
  WeaklyIncrementable& operator++();
  // `output_iterator` requires `i++` to return an iterator,
  // while `weakly_incrementable` requires only that `i++` be well-formed.
  void operator++(int);
};
static_assert( std::weakly_incrementable<WeaklyIncrementable>);
static_assert( std::indirectly_copyable<int*, WeaklyIncrementable>);
static_assert(!std::output_iterator<WeaklyIncrementable, int>);
static_assert( std::mergeable<Input, Input, WeaklyIncrementable>);