brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.5 KiB · 0abf2da Raw
165 lines · c
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#ifndef LIBCXX_TEST_SUPPORT_BOOLEAN_TESTABLE_H10#define LIBCXX_TEST_SUPPORT_BOOLEAN_TESTABLE_H11 12#include "test_macros.h"13 14#include <iterator>15#include <utility>16 17#if TEST_STD_VER > 1718 19struct BooleanTestable {20  constexpr operator bool() const { return value_; }21 22  friend constexpr BooleanTestable operator==(const BooleanTestable& lhs, const BooleanTestable& rhs) {23    return lhs.value_ == rhs.value_;24  }25 26  friend constexpr BooleanTestable operator!=(const BooleanTestable& lhs, const BooleanTestable& rhs) {27    return lhs.value_ != rhs.value_;28  }29 30  constexpr BooleanTestable&& operator!() && {31    value_ = !value_;32    return std::move(*this);33  }34 35  // this class should behave like a bool, so the constructor shouldn't be explicit36  constexpr BooleanTestable(bool value) : value_{value} {}37  constexpr BooleanTestable(const BooleanTestable&) = delete;38  constexpr BooleanTestable(BooleanTestable&&)      = delete;39 40private:41  bool value_;42};43 44static constexpr BooleanTestable yes(true);45static constexpr BooleanTestable no(false);46 47template <class T>48struct StrictComparable {49  StrictComparable() = default;50 51  // this shouldn't be explicit to make it easier to initialize inside arrays (which it almost always is)52  constexpr StrictComparable(T value) : value_{value} {}53 54  friend constexpr BooleanTestable const& operator==(StrictComparable const& a, StrictComparable const& b) {55    return a.value_ == b.value_ ? yes : no;56  }57 58  friend constexpr BooleanTestable const& operator!=(StrictComparable const& a, StrictComparable const& b) {59    return a.value_ != b.value_ ? yes : no;60  }61 62  friend constexpr BooleanTestable const& operator<(StrictComparable const& a, StrictComparable const& b) {63    return a.value_ < b.value_ ? yes : no;64  }65  friend constexpr BooleanTestable const& operator<=(StrictComparable const& a, StrictComparable const& b) {66    return a.value_ <= b.value_ ? yes : no;67  }68  friend constexpr BooleanTestable const& operator>(StrictComparable const& a, StrictComparable const& b) {69    return a.value_ > b.value_ ? yes : no;70  }71  friend constexpr BooleanTestable const& operator>=(StrictComparable const& a, StrictComparable const& b) {72    return a.value_ >= b.value_ ? yes : no;73  }74 75  T value_;76};77 78auto StrictUnaryPredicate = []<class T>(StrictComparable<T> const& x) -> BooleanTestable const& {79  return x.value_ < 0 ? yes : no;80};81 82auto StrictBinaryPredicate =83    []<class T>(StrictComparable<T> const& x, StrictComparable<T> const& y) -> BooleanTestable const& {84  return x.value_ < y.value_ ? yes : no;85};86 87template <class It>88struct StrictBooleanIterator {89  using value_type                  = typename std::iterator_traits<It>::value_type;90  using reference                   = typename std::iterator_traits<It>::reference;91  using difference_type             = typename std::iterator_traits<It>::difference_type;92  constexpr StrictBooleanIterator() = default;93  constexpr explicit StrictBooleanIterator(It it) : iter_(it) {}94  constexpr reference operator*() const { return *iter_; }95  constexpr reference operator[](difference_type n) const { return iter_[n]; }96  constexpr StrictBooleanIterator& operator++() {97    ++iter_;98    return *this;99  }100  constexpr StrictBooleanIterator operator++(int) {101    auto copy = *this;102    ++iter_;103    return copy;104  }105  constexpr StrictBooleanIterator& operator--() {106    --iter_;107    return *this;108  }109  constexpr StrictBooleanIterator operator--(int) {110    auto copy = *this;111    --iter_;112    return copy;113  }114  constexpr StrictBooleanIterator& operator+=(difference_type n) {115    iter_ += n;116    return *this;117  }118  constexpr StrictBooleanIterator& operator-=(difference_type n) {119    iter_ -= n;120    return *this;121  }122  friend constexpr StrictBooleanIterator operator+(StrictBooleanIterator x, difference_type n) {123    x += n;124    return x;125  }126  friend constexpr StrictBooleanIterator operator+(difference_type n, StrictBooleanIterator x) {127    x += n;128    return x;129  }130  friend constexpr StrictBooleanIterator operator-(StrictBooleanIterator x, difference_type n) {131    x -= n;132    return x;133  }134  friend constexpr difference_type operator-(StrictBooleanIterator x, StrictBooleanIterator y) {135    return x.iter_ - y.iter_;136  }137  constexpr BooleanTestable const& operator==(StrictBooleanIterator const& other) const {138    return iter_ == other.iter_ ? yes : no;139  }140  constexpr BooleanTestable const& operator!=(StrictBooleanIterator const& other) const {141    return iter_ != other.iter_ ? yes : no;142  }143  constexpr BooleanTestable const& operator<(StrictBooleanIterator const& other) const {144    return iter_ < other.iter_ ? yes : no;145  }146  constexpr BooleanTestable const& operator<=(StrictBooleanIterator const& other) const {147    return iter_ <= other.iter_ ? yes : no;148  }149  constexpr BooleanTestable const& operator>(StrictBooleanIterator const& other) const {150    return iter_ > other.iter_ ? yes : no;151  }152  constexpr BooleanTestable const& operator>=(StrictBooleanIterator const& other) const {153    return iter_ >= other.iter_ ? yes : no;154  }155 156private:157  It iter_;158};159static_assert(std::forward_iterator<StrictBooleanIterator<int*>>);160static_assert(std::sentinel_for<StrictBooleanIterator<int*>, StrictBooleanIterator<int*>>);161 162#endif // TEST_STD_VER > 17163 164#endif // LIBCXX_TEST_SUPPORT_BOOLEAN_TESTABLE_H165