brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.5 KiB · b0a74b8 Raw
175 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// <algorithm>10 11// template<ForwardIterator Iter, class T>12//   requires OutputIterator<Iter, const T&>13//   constexpr void      // constexpr after C++1714//   fill(Iter first, Iter last, const T& value);15 16#include <algorithm>17#include <array>18#include <cassert>19#include <cstddef>20#include <deque>21#include <ranges>22#include <vector>23 24#include "sized_allocator.h"25#include "test_macros.h"26#include "test_iterators.h"27#include "type_algorithms.h"28 29template <class Iter, class Container>30TEST_CONSTEXPR_CXX20 void31test(Container in, size_t from, size_t to, typename Container::value_type value, Container expected) {32  std::fill(Iter(in.data() + from), Iter(in.data() + to), value);33  assert(in == expected);34}35 36template <class T>37struct Test {38  template <class Iter>39  TEST_CONSTEXPR_CXX20 void operator()() {40    {41      std::array<T, 4> in       = {1, 2, 3, 4};42      std::array<T, 4> expected = {5, 5, 5, 5};43      test<Iter>(in, 0, 4, 5, expected);44    }45    {46      std::array<T, 4> in       = {1, 2, 3, 4};47      std::array<T, 4> expected = {1, 5, 5, 4};48      test<Iter>(in, 1, 3, 5, expected);49    }50  }51};52 53TEST_CONSTEXPR_CXX20 bool test_vector_bool(std::size_t N) {54  {   // Test cases validating leading/trailing bits unfilled remain unchanged55    { // Leading bits are not filled56      std::vector<bool> in(N, false);57      std::vector<bool> expected(N, true);58      expected[0] = expected[1] = false;59      std::fill(in.begin() + 2, in.end(), true);60      assert(in == expected);61    }62    { // Trailing bits are not filled63      std::vector<bool> in(N, false);64      std::vector<bool> expected(N, true);65      expected[N - 1] = expected[N - 2] = false;66      std::fill(in.begin(), in.end() - 2, true);67      assert(in == expected);68    }69    { // Leading and trailing bits are not filled70      std::vector<bool> in(N, false);71      std::vector<bool> expected(N, true);72      expected[0] = expected[1] = expected[N - 1] = expected[N - 2] = false;73      std::fill(in.begin() + 2, in.end() - 2, true);74      assert(in == expected);75    }76  }77 78  {   // Test cases with full or partial bytes filled79    { // Full bytes filled80      std::vector<bool> in(N, false);81      std::vector<bool> expected(N, true);82      std::fill(in.begin(), in.end(), true);83      assert(in == expected);84    }85    { // Partial bytes with offset filled86      std::vector<bool> in(N, false);87      std::vector<bool> expected(N, true);88      std::fill(in.begin() + 4, in.end() - 4, true);89      std::fill(expected.begin(), expected.begin() + 4, false);90      std::fill(expected.end() - 4, expected.end(), false);91      assert(in == expected);92    }93  }94 95  return true;96}97 98/*TEST_CONSTEXPR_CXX26*/ void test_deque() { // TODO: Mark as TEST_CONSTEXPR_CXX26 once std::deque is constexpr99  std::deque<int> in(20);100  std::deque<int> expected(in.size(), 42);101  std::fill(in.begin(), in.end(), 42);102  assert(in == expected);103}104 105TEST_CONSTEXPR_CXX20 bool test() {106  types::for_each(types::forward_iterator_list<char*>(), Test<char>());107  types::for_each(types::forward_iterator_list<int*>(), Test<int>());108 109  { // Test vector<bool>::iterator optimization110    assert(test_vector_bool(8));111    assert(test_vector_bool(19));112    assert(test_vector_bool(32));113    assert(test_vector_bool(49));114    assert(test_vector_bool(64));115    assert(test_vector_bool(199));116    assert(test_vector_bool(256));117 118    // Make sure std::fill behaves properly with std::vector<bool> iterators with custom size types.119    // See https://github.com/llvm/llvm-project/pull/122410.120    {121      using Alloc = sized_allocator<bool, std::uint8_t, std::int8_t>;122      std::vector<bool, Alloc> in(100, false, Alloc(1));123      std::vector<bool, Alloc> expected(100, true, Alloc(1));124      std::fill(in.begin(), in.end(), true);125      assert(in == expected);126    }127    {128      using Alloc = sized_allocator<bool, std::uint16_t, std::int16_t>;129      std::vector<bool, Alloc> in(200, false, Alloc(1));130      std::vector<bool, Alloc> expected(200, true, Alloc(1));131      std::fill(in.begin(), in.end(), true);132      assert(in == expected);133    }134    {135      using Alloc = sized_allocator<bool, std::uint32_t, std::int32_t>;136      std::vector<bool, Alloc> in(200, false, Alloc(1));137      std::vector<bool, Alloc> expected(200, true, Alloc(1));138      std::fill(in.begin(), in.end(), true);139      assert(in == expected);140    }141    {142      using Alloc = sized_allocator<bool, std::uint64_t, std::int64_t>;143      std::vector<bool, Alloc> in(200, false, Alloc(1));144      std::vector<bool, Alloc> expected(200, true, Alloc(1));145      std::fill(in.begin(), in.end(), true);146      assert(in == expected);147    }148  }149 150  if (!TEST_IS_CONSTANT_EVALUATED) // TODO: Use TEST_STD_AT_LEAST_26_OR_RUNTIME_EVALUATED when std::deque is made constexpr151    test_deque();152 153#if TEST_STD_VER >= 20154  { // Verify that join_view of vectors work properly.155    std::vector<std::vector<int>> v{{1, 2}, {1, 2, 3}, {}, {3, 4, 5}, {6}, {7, 8, 9, 6}, {0, 1, 2, 3, 0, 1, 2}};156    auto jv = std::ranges::join_view(v);157    std::fill(jv.begin(), jv.end(), 42);158    for (const auto& vec : v)159      for (auto n : vec)160        assert(n == 42);161  }162#endif163 164  return true;165}166 167int main(int, char**) {168  test();169#if TEST_STD_VER >= 20170  static_assert(test());171#endif172 173  return 0;174}175