brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.5 KiB · bd51d0e Raw
128 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++14, c++1710 11// template<class I1, class I2, class Out,12//     class R = ranges::less, class P1 = identity, class P2 = identity>13//   concept mergeable = see below;                           // since C++2014 15#include <iterator>16 17#include <functional>18 19#include "test_iterators.h"20#include "test_macros.h"21 22using CompDefault = std::ranges::less;23using CompInt = bool(*)(int, int);24using ProjDefault = std::identity;25 26using Input = cpp20_input_iterator<int*>;27static_assert( std::input_iterator<Input>);28using InputLong = cpp20_input_iterator<long*>;29static_assert( std::input_iterator<InputLong>);30 31using Output = cpp17_output_iterator<int*>;32static_assert( std::weakly_incrementable<Output>);33 34static_assert( std::indirectly_copyable<Input, Output>);35static_assert( std::indirectly_copyable<InputLong, Output>);36static_assert( std::indirect_strict_weak_order<CompDefault, Input, Input>);37static_assert( std::indirect_strict_weak_order<CompInt, Input, Input>);38static_assert( std::indirect_strict_weak_order<CompDefault, Input, InputLong>);39static_assert( std::indirect_strict_weak_order<CompInt, Input, InputLong>);40 41// All requirements satisfied.42static_assert( std::mergeable<Input, Input, Output>);43static_assert( std::mergeable<Input, Input, Output, CompInt>);44static_assert( std::mergeable<Input, Input, Output, CompInt, ProjDefault>);45 46// Non-default projections.47struct Foo {};48using ProjFooToInt = int(*)(Foo);49using ProjFooToLong = long(*)(Foo);50static_assert( std::indirect_strict_weak_order<CompDefault,51    std::projected<Foo*, ProjFooToInt>, std::projected<Foo*, ProjFooToLong>>);52static_assert( std::mergeable<Foo*, Foo*, Foo*, CompDefault, ProjFooToInt, ProjFooToLong>);53static_assert( std::indirect_strict_weak_order<CompInt,54    std::projected<Foo*, ProjFooToInt>, std::projected<Foo*, ProjFooToLong>>);55static_assert( std::mergeable<Foo*, Foo*, Foo*, CompInt, ProjFooToInt, ProjFooToLong>);56 57// I1 or I2 is not an input iterator.58static_assert(!std::input_iterator<Output>);59static_assert(!std::mergeable<Output, Input, Output>);60static_assert(!std::mergeable<Input, Output, Output>);61 62// O is not weakly incrementable.63struct NotWeaklyIncrementable {64  int& operator*() const;65};66 67static_assert(!std::weakly_incrementable<NotWeaklyIncrementable>);68static_assert( std::indirectly_copyable<Input, NotWeaklyIncrementable>);69static_assert( std::indirect_strict_weak_order<CompDefault, Input, Input>);70static_assert(!std::mergeable<Input, Input, NotWeaklyIncrementable>);71 72// I1 or I2 is not indirectly copyable into O.73struct AssignableOnlyFromInt {74  AssignableOnlyFromInt& operator=(int);75  template <class T>76  AssignableOnlyFromInt& operator=(T) = delete;77};78using OutputOnlyInt = cpp17_output_iterator<AssignableOnlyFromInt*>;79static_assert( std::weakly_incrementable<OutputOnlyInt>);80 81static_assert( std::indirectly_copyable<Input, OutputOnlyInt>);82static_assert(!std::indirectly_copyable<InputLong, OutputOnlyInt>);83static_assert( std::indirect_strict_weak_order<CompDefault, Input, InputLong>);84static_assert( std::mergeable<Input, Input, OutputOnlyInt>);85static_assert(!std::mergeable<Input, InputLong, OutputOnlyInt>);86static_assert(!std::mergeable<InputLong, Input, OutputOnlyInt>);87 88// No indirect strict weak order between I1 and I2 (bad comparison functor).89using GoodComp = bool(*)(int, int);90static_assert( std::indirect_strict_weak_order<GoodComp, Input, Input>);91static_assert( std::mergeable<Input, Input, Output, GoodComp>);92using BadComp = bool(*)(int*, int*);93static_assert(!std::indirect_strict_weak_order<BadComp, Input, Input>);94static_assert(!std::mergeable<Input, Input, Output, BadComp>);95 96// No indirect strict weak order between I1 and I2 (bad projection).97using ToInt = int(*)(int);98using ToPtr = int*(*)(int);99static_assert( std::mergeable<Input, Input, Output, GoodComp, std::identity, std::identity>);100static_assert( std::mergeable<Input, Input, Output, GoodComp, ToInt, ToInt>);101static_assert(!std::mergeable<Input, Input, Output, GoodComp, ToPtr, ToInt>);102static_assert(!std::mergeable<Input, Input, Output, GoodComp, ToInt, ToPtr>);103static_assert(!std::mergeable<Input, Input, Output, bool(*)(int*, int), ToPtr, ToInt>);104static_assert(!std::mergeable<Input, Input, Output, bool(*)(int, int*), ToInt, ToPtr>);105 106// A projection that only supports non-const references and has a non-const `operator()` still has to work.107struct ProjectionOnlyMutable {108  int operator()(int&);109  int operator()(int&&) const = delete;110};111static_assert( std::mergeable<Input, Input, Output, CompDefault, ProjectionOnlyMutable, ProjectionOnlyMutable>);112 113// The output is weakly incrementable but not an output iterator.114struct WeaklyIncrementable {115  using value_type = int;116  using difference_type = int;117 118  int& operator*() const;119  WeaklyIncrementable& operator++();120  // `output_iterator` requires `i++` to return an iterator,121  // while `weakly_incrementable` requires only that `i++` be well-formed.122  void operator++(int);123};124static_assert( std::weakly_incrementable<WeaklyIncrementable>);125static_assert( std::indirectly_copyable<int*, WeaklyIncrementable>);126static_assert(!std::output_iterator<WeaklyIncrementable, int>);127static_assert( std::mergeable<Input, Input, WeaklyIncrementable>);128