brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.8 KiB · 4cd4458 Raw
186 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// <numeric>10 11// Became constexpr in C++2012// template <InputIterator InIter,13//           OutputIterator<auto, const InIter::value_type&> OutIter,14//           Callable<auto, const InIter::value_type&, const InIter::value_type&> BinaryOperation>15//   requires Constructible<InIter::value_type, InIter::reference>16//         && OutputIterator<OutIter, BinaryOperation::result_type>17//         && MoveAssignable<InIter::value_type>18//         && CopyConstructible<BinaryOperation>19//   OutIter20//   adjacent_difference(InIter first, InIter last, OutIter result, BinaryOperation binary_op);21 22#include <numeric>23#include <functional>24#include <string>25#include <cassert>26 27#include "test_macros.h"28#include "test_iterators.h"29 30#if TEST_STD_VER > 1731struct rvalue_subtractable32{33    bool correctOperatorUsed = false;34 35    // make sure the predicate is passed an rvalue and an lvalue (so check that the first argument was moved)36    constexpr rvalue_subtractable operator()(rvalue_subtractable const&, rvalue_subtractable&& r) {37        r.correctOperatorUsed = true;38        return std::move(r);39    }40};41 42constexpr rvalue_subtractable operator-(rvalue_subtractable const&, rvalue_subtractable& rhs)43{44    rhs.correctOperatorUsed = false;45    return rhs;46}47 48constexpr rvalue_subtractable operator-(rvalue_subtractable const&, rvalue_subtractable&& rhs)49{50    rhs.correctOperatorUsed = true;51    return std::move(rhs);52}53 54constexpr void55test_use_move()56{57    const std::size_t size = 100;58    rvalue_subtractable arr[size];59    rvalue_subtractable res1[size];60    rvalue_subtractable res2[size];61    std::adjacent_difference(arr, arr + size, res1);62    std::adjacent_difference(arr, arr + size, res2, /*predicate=*/rvalue_subtractable());63    // start at 1 because the first element is not moved64    for (unsigned i = 1; i < size; ++i) assert(res1[i].correctOperatorUsed);65    for (unsigned i = 1; i < size; ++i) assert(res2[i].correctOperatorUsed);66}67#endif // TEST_STD_VER > 1768 69TEST_CONSTEXPR_CXX20 void test_string() {70    std::string sa[] = {"a", "b", "c"};71    std::string sr[] = {"a", "ba", "cb"};72    std::string output[3];73    std::adjacent_difference(sa, sa + 3, output, std::plus<std::string>());74    for (unsigned i = 0; i < 3; ++i) assert(output[i] == sr[i]);75}76 77template <class InIter, class OutIter>78TEST_CONSTEXPR_CXX20 void79test()80{81    int ia[] = {15, 10, 6, 3, 1};82    int ir[] = {15, 25, 16, 9, 4};83    const unsigned s = sizeof(ia) / sizeof(ia[0]);84    int ib[s] = {0};85    OutIter r = std::adjacent_difference(InIter(ia), InIter(ia+s), OutIter(ib),86                                         std::plus<int>());87    assert(base(r) == ib + s);88    for (unsigned i = 0; i < s; ++i)89        assert(ib[i] == ir[i]);90}91 92#if TEST_STD_VER >= 1193 94class Y;95 96class X97{98    int i_;99 100    TEST_CONSTEXPR_CXX20 X& operator=(const X&);101public:102    TEST_CONSTEXPR_CXX20 explicit X(int i) : i_(i) {}103    TEST_CONSTEXPR_CXX20 X(const X& x) : i_(x.i_) {}104    TEST_CONSTEXPR_CXX20 X& operator=(X&& x)105    {106        i_ = x.i_;107        x.i_ = -1;108        return *this;109    }110 111    TEST_CONSTEXPR_CXX20 friend X operator-(const X& x, const X& y) {return X(x.i_ - y.i_);}112 113    friend class Y;114};115 116class Y117{118    int i_;119 120    TEST_CONSTEXPR_CXX20 Y& operator=(const Y&);121public:122    TEST_CONSTEXPR_CXX20 explicit Y(int i) : i_(i) {}123    TEST_CONSTEXPR_CXX20 Y(const Y& y) : i_(y.i_) {}124    TEST_CONSTEXPR_CXX20 void operator=(const X& x) {i_ = x.i_;}125};126 127#endif128 129 130TEST_CONSTEXPR_CXX20 bool131test()132{133    test<cpp17_input_iterator<const int*>, cpp17_output_iterator<int*> >();134    test<cpp17_input_iterator<const int*>, forward_iterator<int*> >();135    test<cpp17_input_iterator<const int*>, bidirectional_iterator<int*> >();136    test<cpp17_input_iterator<const int*>, random_access_iterator<int*> >();137    test<cpp17_input_iterator<const int*>, int*>();138 139    test<forward_iterator<const int*>, cpp17_output_iterator<int*> >();140    test<forward_iterator<const int*>, forward_iterator<int*> >();141    test<forward_iterator<const int*>, bidirectional_iterator<int*> >();142    test<forward_iterator<const int*>, random_access_iterator<int*> >();143    test<forward_iterator<const int*>, int*>();144 145    test<bidirectional_iterator<const int*>, cpp17_output_iterator<int*> >();146    test<bidirectional_iterator<const int*>, forward_iterator<int*> >();147    test<bidirectional_iterator<const int*>, bidirectional_iterator<int*> >();148    test<bidirectional_iterator<const int*>, random_access_iterator<int*> >();149    test<bidirectional_iterator<const int*>, int*>();150 151    test<random_access_iterator<const int*>, cpp17_output_iterator<int*> >();152    test<random_access_iterator<const int*>, forward_iterator<int*> >();153    test<random_access_iterator<const int*>, bidirectional_iterator<int*> >();154    test<random_access_iterator<const int*>, random_access_iterator<int*> >();155    test<random_access_iterator<const int*>, int*>();156 157    test<const int*, cpp17_output_iterator<int*> >();158    test<const int*, forward_iterator<int*> >();159    test<const int*, bidirectional_iterator<int*> >();160    test<const int*, random_access_iterator<int*> >();161    test<const int*, int*>();162 163#if TEST_STD_VER >= 11164    X x[3] = {X(1), X(2), X(3)};165    Y y[3] = {Y(1), Y(2), Y(3)};166    std::adjacent_difference(x, x+3, y, std::minus<X>());167#endif168 169#if TEST_STD_VER > 17170    test_use_move();171#endif // TEST_STD_VER > 17172 173    test_string();174 175    return true;176}177 178int main(int, char**)179{180    test();181#if TEST_STD_VER > 17182    static_assert(test());183#endif184    return 0;185}186