15a83710eSEric Fiselier //===----------------------------------------------------------------------===//
25a83710eSEric Fiselier //
357b08b09SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
457b08b09SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
557b08b09SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65a83710eSEric Fiselier //
75a83710eSEric Fiselier //===----------------------------------------------------------------------===//
85a83710eSEric Fiselier
95a83710eSEric Fiselier // <algorithm>
105a83710eSEric Fiselier
115a83710eSEric Fiselier // template<InputIterator InIter, typename OutIter,
125a83710eSEric Fiselier // Predicate<auto, InIter::value_type> Pred, class T>
135a83710eSEric Fiselier // requires OutputIterator<OutIter, InIter::reference>
145a83710eSEric Fiselier // && OutputIterator<OutIter, const T&>
155a83710eSEric Fiselier // && CopyConstructible<Pred>
1612c7423fSMarshall Clow // constexpr OutIter // constexpr after C++17
175a83710eSEric Fiselier // replace_copy_if(InIter first, InIter last, OutIter result, Pred pred, const T& new_value);
185a83710eSEric Fiselier
195a83710eSEric Fiselier #include <algorithm>
205a83710eSEric Fiselier #include <functional>
215a83710eSEric Fiselier #include <cassert>
225a83710eSEric Fiselier
2312c7423fSMarshall Clow #include "test_macros.h"
245a83710eSEric Fiselier #include "test_iterators.h"
255a83710eSEric Fiselier
equalToTwo(int v)2612c7423fSMarshall Clow TEST_CONSTEXPR bool equalToTwo(int v) { return v == 2; }
2712c7423fSMarshall Clow
2812c7423fSMarshall Clow
2912c7423fSMarshall Clow #if TEST_STD_VER > 17
test_constexpr()3012c7423fSMarshall Clow TEST_CONSTEXPR bool test_constexpr() {
3112c7423fSMarshall Clow int ia[] = {0, 1, 2, 3, 4};
3212c7423fSMarshall Clow int ib[] = {0, 0, 0, 0, 0, 0}; // one bigger
3312c7423fSMarshall Clow const int expected[] = {0, 1, 5, 3, 4};
3412c7423fSMarshall Clow
3512c7423fSMarshall Clow auto it = std::replace_copy_if(std::begin(ia), std::end(ia), std::begin(ib), equalToTwo, 5);
3612c7423fSMarshall Clow
3712c7423fSMarshall Clow return it == (std::begin(ib) + std::size(ia))
3812c7423fSMarshall Clow && *it == 0 // don't overwrite the last value in the output array
3912c7423fSMarshall Clow && std::equal(std::begin(ib), it, std::begin(expected), std::end(expected))
4012c7423fSMarshall Clow ;
4112c7423fSMarshall Clow }
4212c7423fSMarshall Clow #endif
43315cd1feSMarshall Clow
445a83710eSEric Fiselier template <class InIter, class OutIter>
455a83710eSEric Fiselier void
test()465a83710eSEric Fiselier test()
475a83710eSEric Fiselier {
485a83710eSEric Fiselier int ia[] = {0, 1, 2, 3, 4};
495a83710eSEric Fiselier const unsigned sa = sizeof(ia)/sizeof(ia[0]);
505a83710eSEric Fiselier int ib[sa] = {0};
51315cd1feSMarshall Clow OutIter r = std::replace_copy_if(InIter(ia), InIter(ia+sa),
52315cd1feSMarshall Clow OutIter(ib), equalToTwo, 5);
535a83710eSEric Fiselier assert(base(r) == ib + sa);
545a83710eSEric Fiselier assert(ib[0] == 0);
555a83710eSEric Fiselier assert(ib[1] == 1);
565a83710eSEric Fiselier assert(ib[2] == 5);
575a83710eSEric Fiselier assert(ib[3] == 3);
585a83710eSEric Fiselier assert(ib[4] == 4);
595a83710eSEric Fiselier }
605a83710eSEric Fiselier
main(int,char **)612df59c50SJF Bastien int main(int, char**)
625a83710eSEric Fiselier {
63*5e97d37bSMark de Wever test<cpp17_input_iterator<const int*>, cpp17_output_iterator<int*> >();
64773ae441SChristopher Di Bella test<cpp17_input_iterator<const int*>, forward_iterator<int*> >();
65773ae441SChristopher Di Bella test<cpp17_input_iterator<const int*>, bidirectional_iterator<int*> >();
66773ae441SChristopher Di Bella test<cpp17_input_iterator<const int*>, random_access_iterator<int*> >();
67773ae441SChristopher Di Bella test<cpp17_input_iterator<const int*>, int*>();
685a83710eSEric Fiselier
69*5e97d37bSMark de Wever test<forward_iterator<const int*>, cpp17_output_iterator<int*> >();
705a83710eSEric Fiselier test<forward_iterator<const int*>, forward_iterator<int*> >();
715a83710eSEric Fiselier test<forward_iterator<const int*>, bidirectional_iterator<int*> >();
725a83710eSEric Fiselier test<forward_iterator<const int*>, random_access_iterator<int*> >();
735a83710eSEric Fiselier test<forward_iterator<const int*>, int*>();
745a83710eSEric Fiselier
75*5e97d37bSMark de Wever test<bidirectional_iterator<const int*>, cpp17_output_iterator<int*> >();
765a83710eSEric Fiselier test<bidirectional_iterator<const int*>, forward_iterator<int*> >();
775a83710eSEric Fiselier test<bidirectional_iterator<const int*>, bidirectional_iterator<int*> >();
785a83710eSEric Fiselier test<bidirectional_iterator<const int*>, random_access_iterator<int*> >();
795a83710eSEric Fiselier test<bidirectional_iterator<const int*>, int*>();
805a83710eSEric Fiselier
81*5e97d37bSMark de Wever test<random_access_iterator<const int*>, cpp17_output_iterator<int*> >();
825a83710eSEric Fiselier test<random_access_iterator<const int*>, forward_iterator<int*> >();
835a83710eSEric Fiselier test<random_access_iterator<const int*>, bidirectional_iterator<int*> >();
845a83710eSEric Fiselier test<random_access_iterator<const int*>, random_access_iterator<int*> >();
855a83710eSEric Fiselier test<random_access_iterator<const int*>, int*>();
865a83710eSEric Fiselier
87*5e97d37bSMark de Wever test<const int*, cpp17_output_iterator<int*> >();
885a83710eSEric Fiselier test<const int*, forward_iterator<int*> >();
895a83710eSEric Fiselier test<const int*, bidirectional_iterator<int*> >();
905a83710eSEric Fiselier test<const int*, random_access_iterator<int*> >();
915a83710eSEric Fiselier test<const int*, int*>();
9212c7423fSMarshall Clow
9312c7423fSMarshall Clow #if TEST_STD_VER > 17
9412c7423fSMarshall Clow static_assert(test_constexpr());
9512c7423fSMarshall Clow #endif
962df59c50SJF Bastien
972df59c50SJF Bastien return 0;
985a83710eSEric Fiselier }
99