98 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<InputIterator Iter, class T>12// requires HasEqualTo<Iter::value_type, T>13// constexpr Iter::difference_type // constexpr after C++1714// count(Iter first, Iter last, const T& value);15 16// ADDITIONAL_COMPILE_FLAGS(has-fconstexpr-steps): -fconstexpr-steps=2000000017// ADDITIONAL_COMPILE_FLAGS(has-fconstexpr-ops-limit): -fconstexpr-ops-limit=8000000018 19#include <algorithm>20#include <cassert>21#include <cstddef>22#include <cstdint>23#include <vector>24 25#include "sized_allocator.h"26#include "test_macros.h"27#include "test_iterators.h"28#include "type_algorithms.h"29 30struct Test {31 template <class Iter>32 TEST_CONSTEXPR_CXX20 void operator()() {33 int ia[] = {0, 1, 2, 2, 0, 1, 2, 3};34 const unsigned sa = sizeof(ia) / sizeof(ia[0]);35 assert(std::count(Iter(ia), Iter(ia + sa), 2) == 3);36 assert(std::count(Iter(ia), Iter(ia + sa), 7) == 0);37 assert(std::count(Iter(ia), Iter(ia), 2) == 0);38 }39};40 41TEST_CONSTEXPR_CXX20 bool test() {42 types::for_each(types::cpp17_input_iterator_list<const int*>(), Test());43 44 // Tests for std::count with std::vector<bool>::iterator optimizations.45 {46 { // check that vector<bool>::iterator optimization works as expected47 std::vector<bool> vec(256 + 64);48 for (ptrdiff_t i = 0; i != 256; ++i) {49 for (size_t offset = 0; offset != 64; ++offset) {50 std::fill(vec.begin(), vec.end(), false);51 std::fill(vec.begin() + offset, vec.begin() + i + offset, true);52 assert(std::count(vec.begin() + offset, vec.begin() + offset + 256, true) == i);53 assert(std::count(vec.begin() + offset, vec.begin() + offset + 256, false) == 256 - i);54 }55 }56 }57 58 // Fix std::count for std::vector<bool> with small storage types, e.g., std::uint16_t, unsigned short.59 // See https://llvm.org/PR12252860 {61 using Alloc = sized_allocator<bool, std::uint8_t, std::int8_t>;62 std::vector<bool, Alloc> in(100, true, Alloc(1));63 assert(std::count(in.begin(), in.end(), true) == 100);64 }65 {66 using Alloc = sized_allocator<bool, std::uint16_t, std::int16_t>;67 std::vector<bool, Alloc> in(199, true, Alloc(1));68 assert(std::count(in.begin(), in.end(), true) == 199);69 }70 {71 using Alloc = sized_allocator<bool, unsigned short, short>;72 std::vector<bool, Alloc> in(200, true, Alloc(1));73 assert(std::count(in.begin(), in.end(), true) == 200);74 }75 {76 using Alloc = sized_allocator<bool, std::uint32_t, std::int32_t>;77 std::vector<bool, Alloc> in(205, true, Alloc(1));78 assert(std::count(in.begin(), in.end(), true) == 205);79 }80 {81 using Alloc = sized_allocator<bool, std::uint64_t, std::int64_t>;82 std::vector<bool, Alloc> in(257, true, Alloc(1));83 assert(std::count(in.begin(), in.end(), true) == 257);84 }85 }86 87 return true;88}89 90int main(int, char**) {91 test();92#if TEST_STD_VER >= 2093 static_assert(test());94#endif95 96 return 0;97}98