brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.7 KiB · 56f12e0 Raw
177 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 10// <iterator>11 12// __libcpp_is_contiguous_iterator<_Tp>13 14// __libcpp_is_contiguous_iterator determines if an iterator is contiguous,15// either because it advertises itself as such (in C++20) or because it16// is a pointer type or a known trivial wrapper around a pointer type,17// such as __wrap_iter<T*>.18//19 20#include <cassert>21#include <deque>22#include <initializer_list>23#include <iterator>24#include <string>25#include <vector>26 27#include "test_macros.h"28#include "test_iterators.h"29 30class T;  // incomplete31 32class my_input_iterator33{34    struct tag : std::input_iterator_tag {};35    typedef my_input_iterator Self;36    int *state_;37public:38    typedef tag iterator_category;39    typedef int value_type;40    typedef int difference_type;41    typedef int* pointer;42    typedef int& reference;43 44    my_input_iterator();45    reference operator*() const;46    pointer operator->() const;47 48    Self& operator++();49    Self operator++(int);50    friend bool operator==(const Self&, const Self&);51    friend bool operator!=(const Self&, const Self&);52};53 54class my_random_access_iterator55{56    struct tag : std::random_access_iterator_tag {};57    typedef my_random_access_iterator Self;58    int *state_;59public:60    typedef tag iterator_category;61    typedef int value_type;62    typedef int difference_type;63    typedef int* pointer;64    typedef int& reference;65 66    my_random_access_iterator();67    reference operator*() const;68    pointer operator->() const;69    reference operator[](difference_type) const;70 71    Self& operator++();72    Self operator++(int);73    Self& operator--();74    Self operator--(int);75    friend Self& operator+=(Self&, difference_type);76    friend Self& operator-=(Self&, difference_type);77    friend Self operator+(Self, difference_type);78    friend Self operator+(difference_type, Self);79    friend Self operator-(Self, difference_type);80    friend difference_type operator-(Self, Self);81    friend bool operator==(const Self&, const Self&);82    friend bool operator!=(const Self&, const Self&);83    friend bool operator<(const Self&, const Self&);84    friend bool operator>(const Self&, const Self&);85    friend bool operator<=(const Self&, const Self&);86    friend bool operator>=(const Self&, const Self&);87};88 89struct fake_deque_iterator : std::deque<int>::iterator {90    using element_type = int;91};92static_assert(std::__has_random_access_iterator_category<fake_deque_iterator>::value, "");93static_assert(!std::__libcpp_is_contiguous_iterator<fake_deque_iterator>::value, "");94 95int main(int, char**)96{97//  basic tests98    static_assert(( std::__libcpp_is_contiguous_iterator<char *>::value), "");99    static_assert(( std::__libcpp_is_contiguous_iterator<const char *>::value), "");100    static_assert(( std::__libcpp_is_contiguous_iterator<int *>::value), "");101    static_assert(( std::__libcpp_is_contiguous_iterator<int **>::value), "");102    static_assert(( std::__libcpp_is_contiguous_iterator<T *>::value), "");103 104    static_assert((!std::__libcpp_is_contiguous_iterator<my_input_iterator>::value), "");105    static_assert((!std::__libcpp_is_contiguous_iterator<my_random_access_iterator>::value), "");106 107    // move_iterator changes value category, which makes it pretty sketchy to use in optimized codepaths108    static_assert((!std::__libcpp_is_contiguous_iterator<std::move_iterator<char *> >::value), "");109    static_assert((!std::__libcpp_is_contiguous_iterator<std::move_iterator<const char *> >::value), "");110    static_assert((!std::__libcpp_is_contiguous_iterator<std::move_iterator<int *> >::value), "");111    static_assert((!std::__libcpp_is_contiguous_iterator<std::move_iterator<T *> >::value), "");112    static_assert((!std::__libcpp_is_contiguous_iterator<std::move_iterator<my_random_access_iterator> >::value), "");113 114    static_assert((!std::__libcpp_is_contiguous_iterator<std::reverse_iterator<char *> >::value), "");115    static_assert((!std::__libcpp_is_contiguous_iterator<std::reverse_iterator<const char *> >::value), "");116    static_assert((!std::__libcpp_is_contiguous_iterator<std::reverse_iterator<int *> >::value), "");117    static_assert((!std::__libcpp_is_contiguous_iterator<std::reverse_iterator<T *> >::value), "");118    static_assert((!std::__libcpp_is_contiguous_iterator<std::reverse_iterator<my_random_access_iterator> >::value), "");119 120    static_assert(( std::__libcpp_is_contiguous_iterator<std::__wrap_iter<char *> >::value), "");121    static_assert(( std::__libcpp_is_contiguous_iterator<std::__wrap_iter<const char *> >::value), "");122    static_assert(( std::__libcpp_is_contiguous_iterator<std::__wrap_iter<int *> >::value), "");123 124    static_assert(( std::__libcpp_is_contiguous_iterator<std::__wrap_iter<T *> >::value), "");125    static_assert(( std::__libcpp_is_contiguous_iterator<std::__wrap_iter<std::__wrap_iter<T *> > >::value), "");126 127    // Here my_random_access_iterator is standing in for some user's fancy pointer type, written pre-C++20.128    static_assert(( std::__libcpp_is_contiguous_iterator<std::__wrap_iter<my_random_access_iterator> >::value), "");129    static_assert(( std::__libcpp_is_contiguous_iterator<std::__wrap_iter<std::__wrap_iter<my_random_access_iterator> > >::value), "");130 131//  iterators in the libc++ test suite132    static_assert((!std::__libcpp_is_contiguous_iterator<cpp17_output_iterator <char *> >::value), "");133    static_assert((!std::__libcpp_is_contiguous_iterator<cpp17_input_iterator  <char *> >::value), "");134    static_assert((!std::__libcpp_is_contiguous_iterator<forward_iterator      <char *> >::value), "");135    static_assert((!std::__libcpp_is_contiguous_iterator<bidirectional_iterator<char *> >::value), "");136    static_assert((!std::__libcpp_is_contiguous_iterator<random_access_iterator<char *> >::value), "");137    static_assert((!std::__libcpp_is_contiguous_iterator<ThrowingIterator      <char *> >::value), "");138    static_assert((!std::__libcpp_is_contiguous_iterator<NonThrowingIterator   <char *> >::value), "");139 140//141//  iterators from libc++'s containers142//143 144//  vector145    static_assert(( std::__libcpp_is_contiguous_iterator<std::vector<int>::iterator>                   ::value), "");146    static_assert(( std::__libcpp_is_contiguous_iterator<std::vector<int>::const_iterator>             ::value), "");147    static_assert((!std::__libcpp_is_contiguous_iterator<std::vector<int>::reverse_iterator>           ::value), "");148    static_assert((!std::__libcpp_is_contiguous_iterator<std::vector<int>::const_reverse_iterator>     ::value), "");149    static_assert(( std::__libcpp_is_contiguous_iterator<std::__wrap_iter<std::vector<int>::iterator> >::value), "");150 151//  string152    static_assert(( std::__libcpp_is_contiguous_iterator<std::string::iterator>              ::value), "");153    static_assert(( std::__libcpp_is_contiguous_iterator<std::string::const_iterator>        ::value), "");154    static_assert((!std::__libcpp_is_contiguous_iterator<std::string::reverse_iterator>      ::value), "");155    static_assert((!std::__libcpp_is_contiguous_iterator<std::string::const_reverse_iterator>::value), "");156#ifndef TEST_HAS_NO_WIDE_CHARACTERS157    static_assert(( std::__libcpp_is_contiguous_iterator<std::wstring::iterator>              ::value), "");158    static_assert(( std::__libcpp_is_contiguous_iterator<std::wstring::const_iterator>        ::value), "");159    static_assert((!std::__libcpp_is_contiguous_iterator<std::wstring::reverse_iterator>      ::value), "");160    static_assert((!std::__libcpp_is_contiguous_iterator<std::wstring::const_reverse_iterator>::value), "");161#endif162 163//  deque is random-access but not contiguous164    static_assert((!std::__libcpp_is_contiguous_iterator<std::deque<int>::iterator>                   ::value), "");165    static_assert((!std::__libcpp_is_contiguous_iterator<std::deque<int>::const_iterator>             ::value), "");166    static_assert((!std::__libcpp_is_contiguous_iterator<std::deque<int>::reverse_iterator>           ::value), "");167    static_assert((!std::__libcpp_is_contiguous_iterator<std::deque<int>::const_reverse_iterator>     ::value), "");168 169//  vector<bool> is random-access but not contiguous170    static_assert((!std::__libcpp_is_contiguous_iterator<std::vector<bool>::iterator>                   ::value), "");171    static_assert((!std::__libcpp_is_contiguous_iterator<std::vector<bool>::const_iterator>             ::value), "");172    static_assert((!std::__libcpp_is_contiguous_iterator<std::vector<bool>::reverse_iterator>           ::value), "");173    static_assert((!std::__libcpp_is_contiguous_iterator<std::vector<bool>::const_reverse_iterator>     ::value), "");174 175    return 0;176}177