brintos

brintos / llvm-project-archived public Read only

0
0
Text · 12.2 KiB · f00ca4e Raw
266 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 30#if TEST_STD_VER >= 1731#include <string_view>32#endif33 34#if TEST_STD_VER >= 2035#include <span>36#endif37 38class T;  // incomplete39 40class my_input_iterator41{42    struct tag : std::input_iterator_tag {};43    typedef my_input_iterator Self;44    int *state_;45public:46    typedef tag iterator_category;47    typedef int value_type;48    typedef int difference_type;49    typedef int* pointer;50    typedef int& reference;51 52    my_input_iterator();53    reference operator*() const;54    pointer operator->() const;55 56    Self& operator++();57    Self operator++(int);58    friend bool operator==(const Self&, const Self&);59    friend bool operator!=(const Self&, const Self&);60};61 62class my_random_access_iterator63{64    struct tag : std::random_access_iterator_tag {};65    typedef my_random_access_iterator Self;66    int *state_;67public:68    typedef tag iterator_category;69    typedef int value_type;70    typedef int difference_type;71    typedef int* pointer;72    typedef int& reference;73 74    my_random_access_iterator();75    reference operator*() const;76    pointer operator->() const;77    reference operator[](difference_type) const;78 79    Self& operator++();80    Self operator++(int);81    Self& operator--();82    Self operator--(int);83    friend Self& operator+=(Self&, difference_type);84    friend Self& operator-=(Self&, difference_type);85    friend Self operator+(Self, difference_type);86    friend Self operator+(difference_type, Self);87    friend Self operator-(Self, difference_type);88    friend difference_type operator-(Self, Self);89    friend bool operator==(const Self&, const Self&);90    friend bool operator!=(const Self&, const Self&);91    friend bool operator<(const Self&, const Self&);92    friend bool operator>(const Self&, const Self&);93    friend bool operator<=(const Self&, const Self&);94    friend bool operator>=(const Self&, const Self&);95};96 97#if TEST_STD_VER >= 2098class my_contiguous_iterator99{100    struct tag : std::contiguous_iterator_tag {};101    typedef my_contiguous_iterator Self;102    int *state_;103public:104    typedef tag iterator_category;105    typedef int value_type;106    typedef int difference_type;107    typedef int* pointer;108    typedef int& reference;109    typedef int element_type;  // enable to_address via pointer_traits110 111    my_contiguous_iterator();112    reference operator*() const;113    pointer operator->() const;114    reference operator[](difference_type) const;115 116    Self& operator++();117    Self operator++(int);118    Self& operator--();119    Self operator--(int);120    friend Self& operator+=(Self&, difference_type);121    friend Self& operator-=(Self&, difference_type);122    friend Self operator+(Self, difference_type);123    friend Self operator+(difference_type, Self);124    friend Self operator-(Self, difference_type);125    friend difference_type operator-(Self, Self);126    friend bool operator==(const Self&, const Self&);127    friend bool operator!=(const Self&, const Self&);128    friend bool operator<(const Self&, const Self&);129    friend bool operator>(const Self&, const Self&);130    friend bool operator<=(const Self&, const Self&);131    friend bool operator>=(const Self&, const Self&);132};133#endif134 135struct fake_deque_iterator : std::deque<int>::iterator {136    using element_type = int;137};138static_assert(std::__has_random_access_iterator_category<fake_deque_iterator>::value, "");139static_assert(!std::__libcpp_is_contiguous_iterator<fake_deque_iterator>::value, "");140 141#if TEST_STD_VER >= 20142struct fake2_deque_iterator : std::deque<int>::iterator {143    using iterator_concept = std::contiguous_iterator_tag;144    using element_type = int;145};146static_assert(std::__has_random_access_iterator_category<fake2_deque_iterator>::value, "");147static_assert(std::__libcpp_is_contiguous_iterator<fake2_deque_iterator>::value, "");148#endif149 150int main(int, char**)151{152//  basic tests153    static_assert(( std::__libcpp_is_contiguous_iterator<char *>::value), "");154    static_assert(( std::__libcpp_is_contiguous_iterator<const char *>::value), "");155    static_assert(( std::__libcpp_is_contiguous_iterator<int *>::value), "");156    static_assert(( std::__libcpp_is_contiguous_iterator<int **>::value), "");157    static_assert(( std::__libcpp_is_contiguous_iterator<T *>::value), "");158 159    static_assert((!std::__libcpp_is_contiguous_iterator<my_input_iterator>::value), "");160    static_assert((!std::__libcpp_is_contiguous_iterator<my_random_access_iterator>::value), "");161#if TEST_STD_VER >= 20162    static_assert(( std::__libcpp_is_contiguous_iterator<my_contiguous_iterator>::value), "");163#endif164 165    // move_iterator changes value category, which makes it pretty sketchy to use in optimized codepaths166    static_assert((!std::__libcpp_is_contiguous_iterator<std::move_iterator<char *> >::value), "");167    static_assert((!std::__libcpp_is_contiguous_iterator<std::move_iterator<const char *> >::value), "");168    static_assert((!std::__libcpp_is_contiguous_iterator<std::move_iterator<int *> >::value), "");169    static_assert((!std::__libcpp_is_contiguous_iterator<std::move_iterator<T *> >::value), "");170    static_assert((!std::__libcpp_is_contiguous_iterator<std::move_iterator<my_random_access_iterator> >::value), "");171#if TEST_STD_VER >= 20172    static_assert((!std::__libcpp_is_contiguous_iterator<std::move_iterator<my_contiguous_iterator> >::value), "");173#endif174 175    static_assert((!std::__libcpp_is_contiguous_iterator<std::reverse_iterator<char *> >::value), "");176    static_assert((!std::__libcpp_is_contiguous_iterator<std::reverse_iterator<const char *> >::value), "");177    static_assert((!std::__libcpp_is_contiguous_iterator<std::reverse_iterator<int *> >::value), "");178    static_assert((!std::__libcpp_is_contiguous_iterator<std::reverse_iterator<T *> >::value), "");179    static_assert((!std::__libcpp_is_contiguous_iterator<std::reverse_iterator<my_random_access_iterator> >::value), "");180#if TEST_STD_VER >= 20181    static_assert((!std::__libcpp_is_contiguous_iterator<std::reverse_iterator<my_contiguous_iterator> >::value), "");182#endif183 184    static_assert(( std::__libcpp_is_contiguous_iterator<std::__wrap_iter<char *> >::value), "");185    static_assert(( std::__libcpp_is_contiguous_iterator<std::__wrap_iter<const char *> >::value), "");186    static_assert(( std::__libcpp_is_contiguous_iterator<std::__wrap_iter<int *> >::value), "");187 188    static_assert(( std::__libcpp_is_contiguous_iterator<std::__wrap_iter<T *> >::value), "");189    static_assert(( std::__libcpp_is_contiguous_iterator<std::__wrap_iter<std::__wrap_iter<T *> > >::value), "");190 191    // Here my_random_access_iterator is standing in for some user's fancy pointer type, written pre-C++20.192    static_assert(( std::__libcpp_is_contiguous_iterator<std::__wrap_iter<my_random_access_iterator> >::value), "");193    static_assert(( std::__libcpp_is_contiguous_iterator<std::__wrap_iter<std::__wrap_iter<my_random_access_iterator> > >::value), "");194 195#if TEST_STD_VER >= 20196    static_assert(( std::__libcpp_is_contiguous_iterator<std::__wrap_iter<my_contiguous_iterator> >::value), "");197    static_assert(( std::__libcpp_is_contiguous_iterator<std::__wrap_iter<std::__wrap_iter<my_contiguous_iterator> > >::value), "");198#endif199 200//  iterators in the libc++ test suite201    static_assert((!std::__libcpp_is_contiguous_iterator<cpp17_output_iterator <char *> >::value), "");202    static_assert((!std::__libcpp_is_contiguous_iterator<cpp17_input_iterator  <char *> >::value), "");203    static_assert((!std::__libcpp_is_contiguous_iterator<forward_iterator      <char *> >::value), "");204    static_assert((!std::__libcpp_is_contiguous_iterator<bidirectional_iterator<char *> >::value), "");205    static_assert((!std::__libcpp_is_contiguous_iterator<random_access_iterator<char *> >::value), "");206#if TEST_STD_VER >= 20207    static_assert(( std::__libcpp_is_contiguous_iterator<contiguous_iterator   <char *> >::value), "");208#endif209    static_assert((!std::__libcpp_is_contiguous_iterator<ThrowingIterator      <char *> >::value), "");210    static_assert((!std::__libcpp_is_contiguous_iterator<NonThrowingIterator   <char *> >::value), "");211 212//213//  iterators from libc++'s containers214//215 216//  vector217    static_assert(( std::__libcpp_is_contiguous_iterator<std::vector<int>::iterator>                   ::value), "");218    static_assert(( std::__libcpp_is_contiguous_iterator<std::vector<int>::const_iterator>             ::value), "");219    static_assert((!std::__libcpp_is_contiguous_iterator<std::vector<int>::reverse_iterator>           ::value), "");220    static_assert((!std::__libcpp_is_contiguous_iterator<std::vector<int>::const_reverse_iterator>     ::value), "");221    static_assert(( std::__libcpp_is_contiguous_iterator<std::__wrap_iter<std::vector<int>::iterator> >::value), "");222 223//  string224    static_assert(( std::__libcpp_is_contiguous_iterator<std::string::iterator>              ::value), "");225    static_assert(( std::__libcpp_is_contiguous_iterator<std::string::const_iterator>        ::value), "");226    static_assert((!std::__libcpp_is_contiguous_iterator<std::string::reverse_iterator>      ::value), "");227    static_assert((!std::__libcpp_is_contiguous_iterator<std::string::const_reverse_iterator>::value), "");228#ifndef TEST_HAS_NO_WIDE_CHARACTERS229    static_assert(( std::__libcpp_is_contiguous_iterator<std::wstring::iterator>              ::value), "");230    static_assert(( std::__libcpp_is_contiguous_iterator<std::wstring::const_iterator>        ::value), "");231    static_assert((!std::__libcpp_is_contiguous_iterator<std::wstring::reverse_iterator>      ::value), "");232    static_assert((!std::__libcpp_is_contiguous_iterator<std::wstring::const_reverse_iterator>::value), "");233#endif234 235//  deque is random-access but not contiguous236    static_assert((!std::__libcpp_is_contiguous_iterator<std::deque<int>::iterator>                   ::value), "");237    static_assert((!std::__libcpp_is_contiguous_iterator<std::deque<int>::const_iterator>             ::value), "");238    static_assert((!std::__libcpp_is_contiguous_iterator<std::deque<int>::reverse_iterator>           ::value), "");239    static_assert((!std::__libcpp_is_contiguous_iterator<std::deque<int>::const_reverse_iterator>     ::value), "");240 241//  vector<bool> is random-access but not contiguous242    static_assert((!std::__libcpp_is_contiguous_iterator<std::vector<bool>::iterator>                   ::value), "");243    static_assert((!std::__libcpp_is_contiguous_iterator<std::vector<bool>::const_iterator>             ::value), "");244    static_assert((!std::__libcpp_is_contiguous_iterator<std::vector<bool>::reverse_iterator>           ::value), "");245    static_assert((!std::__libcpp_is_contiguous_iterator<std::vector<bool>::const_reverse_iterator>     ::value), "");246 247#if TEST_STD_VER >= 11248    static_assert(( std::__libcpp_is_contiguous_iterator<std::initializer_list<int>::iterator>      ::value), "");249    static_assert(( std::__libcpp_is_contiguous_iterator<std::initializer_list<int>::const_iterator>::value), "");250#endif251 252#if TEST_STD_VER >= 17253    static_assert(( std::__libcpp_is_contiguous_iterator<std::string_view::iterator>      ::value), "");254    static_assert(( std::__libcpp_is_contiguous_iterator<std::string_view::const_iterator>::value), "");255#endif256 257#if TEST_STD_VER >= 20258    static_assert(( std::__libcpp_is_contiguous_iterator<std::span<      int>::iterator>        ::value), "");259    static_assert((!std::__libcpp_is_contiguous_iterator<std::span<      int>::reverse_iterator>::value), "");260    static_assert(( std::__libcpp_is_contiguous_iterator<std::span<const int>::iterator>        ::value), "");261    static_assert((!std::__libcpp_is_contiguous_iterator<std::span<const int>::reverse_iterator>::value), "");262#endif263 264    return 0;265}266