brintos

brintos / llvm-project-archived public Read only

0
0
Text · 11.6 KiB · 357e52a Raw
292 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// UNSUPPORTED: c++03, c++11, c++14, c++1710 11// std::ranges::data12 13#include <ranges>14 15#include <cassert>16#include <type_traits>17#include "test_macros.h"18#include "test_iterators.h"19 20using RangeDataT = decltype(std::ranges::data);21using RangeCDataT = decltype(std::ranges::cdata);22 23static int globalBuff[2];24 25struct Incomplete;26 27static_assert(!std::is_invocable_v<RangeDataT, Incomplete[]>);28static_assert(!std::is_invocable_v<RangeDataT, Incomplete(&&)[2]>);29static_assert(!std::is_invocable_v<RangeDataT, Incomplete(&&)[2][2]>);30static_assert(!std::is_invocable_v<RangeDataT, int [1]>);31static_assert(!std::is_invocable_v<RangeDataT, int (&&)[1]>);32static_assert( std::is_invocable_v<RangeDataT, int (&)[1]>);33 34static_assert(!std::is_invocable_v<RangeCDataT, Incomplete[]>);35static_assert(!std::is_invocable_v<RangeCDataT, Incomplete(&&)[2]>);36static_assert(!std::is_invocable_v<RangeCDataT, Incomplete(&&)[2][2]>);37static_assert(!std::is_invocable_v<RangeCDataT, int [1]>);38static_assert(!std::is_invocable_v<RangeCDataT, int (&&)[1]>);39static_assert( std::is_invocable_v<RangeCDataT, int (&)[1]>);40 41struct DataMember {42  int x;43  constexpr const int *data() const { return &x; }44};45static_assert( std::is_invocable_v<RangeDataT, DataMember &>);46static_assert(!std::is_invocable_v<RangeDataT, DataMember &&>);47static_assert( std::is_invocable_v<RangeDataT, DataMember const&>);48static_assert(!std::is_invocable_v<RangeDataT, DataMember const&&>);49static_assert( std::is_invocable_v<RangeCDataT, DataMember &>);50static_assert(!std::is_invocable_v<RangeCDataT, DataMember &&>);51static_assert( std::is_invocable_v<RangeCDataT, DataMember const&>);52static_assert(!std::is_invocable_v<RangeCDataT, DataMember const&&>);53 54constexpr bool testReturnTypes() {55  {56    int *x[2];57    ASSERT_SAME_TYPE(decltype(std::ranges::data(x)), int**);58    ASSERT_SAME_TYPE(decltype(std::ranges::cdata(x)), int* const*);59  }60  {61    int x[2][2];62    ASSERT_SAME_TYPE(decltype(std::ranges::data(x)), int(*)[2]);63    ASSERT_SAME_TYPE(decltype(std::ranges::cdata(x)), const int(*)[2]);64  }65  {66    struct D {67      char*& data();68      short*& data() const;69    };70    ASSERT_SAME_TYPE(decltype(std::ranges::data(std::declval<D&>())), char*);71    static_assert(!std::is_invocable_v<RangeDataT, D&&>);72    ASSERT_SAME_TYPE(decltype(std::ranges::data(std::declval<const D&>())), short*);73    static_assert(!std::is_invocable_v<RangeDataT, const D&&>);74    ASSERT_SAME_TYPE(decltype(std::ranges::cdata(std::declval<D&>())), short*);75    static_assert(!std::is_invocable_v<RangeCDataT, D&&>);76    ASSERT_SAME_TYPE(decltype(std::ranges::cdata(std::declval<const D&>())), short*);77    static_assert(!std::is_invocable_v<RangeCDataT, const D&&>);78  }79  {80    struct NC {81      char *begin() const;82      char *end() const;83      int *data();84    };85    static_assert(!std::ranges::contiguous_range<NC>);86    static_assert( std::ranges::contiguous_range<const NC>);87    ASSERT_SAME_TYPE(decltype(std::ranges::data(std::declval<NC&>())), int*);88    static_assert(!std::is_invocable_v<RangeDataT, NC&&>);89    ASSERT_SAME_TYPE(decltype(std::ranges::data(std::declval<const NC&>())), char*);90    static_assert(!std::is_invocable_v<RangeDataT, const NC&&>);91    ASSERT_SAME_TYPE(decltype(std::ranges::cdata(std::declval<NC&>())), char*);92    static_assert(!std::is_invocable_v<RangeCDataT, NC&&>);93    ASSERT_SAME_TYPE(decltype(std::ranges::cdata(std::declval<const NC&>())), char*);94    static_assert(!std::is_invocable_v<RangeCDataT, const NC&&>);95  }96  return true;97}98 99struct VoidDataMember {100  void *data() const;101};102static_assert(!std::is_invocable_v<RangeDataT, VoidDataMember const&>);103static_assert(!std::is_invocable_v<RangeCDataT, VoidDataMember const&>);104 105struct Empty { };106struct EmptyDataMember {107  Empty data() const;108};109static_assert(!std::is_invocable_v<RangeDataT, EmptyDataMember const&>);110static_assert(!std::is_invocable_v<RangeCDataT, EmptyDataMember const&>);111 112struct PtrConvertibleDataMember {113  struct Ptr {114    operator int*() const;115  };116  Ptr data() const;117};118static_assert(!std::is_invocable_v<RangeDataT, PtrConvertibleDataMember const&>);119static_assert(!std::is_invocable_v<RangeCDataT, PtrConvertibleDataMember const&>);120 121struct NonConstDataMember {122  int x;123  constexpr int *data() { return &x; }124};125 126struct EnabledBorrowingDataMember {127  constexpr int *data() { return &globalBuff[0]; }128};129template<>130inline constexpr bool std::ranges::enable_borrowed_range<EnabledBorrowingDataMember> = true;131 132struct DataMemberAndBegin {133  int x;134  constexpr const int *data() const { return &x; }135  const int *begin() const;136};137 138constexpr bool testDataMember() {139  DataMember a;140  assert(std::ranges::data(a) == &a.x);141  assert(std::ranges::cdata(a) == &a.x);142 143  NonConstDataMember b;144  assert(std::ranges::data(b) == &b.x);145  static_assert(!std::is_invocable_v<RangeCDataT, decltype((b))>);146 147  EnabledBorrowingDataMember c;148  assert(std::ranges::data(std::move(c)) == &globalBuff[0]);149  static_assert(!std::is_invocable_v<RangeCDataT, decltype(std::move(c))>);150 151  DataMemberAndBegin d;152  assert(std::ranges::data(d) == &d.x);153  assert(std::ranges::cdata(d) == &d.x);154 155  return true;156}157 158using ContiguousIter = contiguous_iterator<const int*>;159 160struct BeginMemberContiguousIterator {161  int buff[8];162 163  constexpr ContiguousIter begin() const { return ContiguousIter(buff); }164};165static_assert( std::is_invocable_v<RangeDataT, BeginMemberContiguousIterator &>);166static_assert(!std::is_invocable_v<RangeDataT, BeginMemberContiguousIterator &&>);167static_assert( std::is_invocable_v<RangeDataT, BeginMemberContiguousIterator const&>);168static_assert(!std::is_invocable_v<RangeDataT, BeginMemberContiguousIterator const&&>);169static_assert( std::is_invocable_v<RangeCDataT, BeginMemberContiguousIterator &>);170static_assert(!std::is_invocable_v<RangeCDataT, BeginMemberContiguousIterator &&>);171static_assert( std::is_invocable_v<RangeCDataT, BeginMemberContiguousIterator const&>);172static_assert(!std::is_invocable_v<RangeCDataT, BeginMemberContiguousIterator const&&>);173 174struct BeginMemberRandomAccess {175  int buff[8];176 177  random_access_iterator<const int*> begin() const;178};179static_assert(!std::is_invocable_v<RangeDataT, BeginMemberRandomAccess&>);180static_assert(!std::is_invocable_v<RangeDataT, BeginMemberRandomAccess&&>);181static_assert(!std::is_invocable_v<RangeDataT, const BeginMemberRandomAccess&>);182static_assert(!std::is_invocable_v<RangeDataT, const BeginMemberRandomAccess&&>);183static_assert(!std::is_invocable_v<RangeCDataT, BeginMemberRandomAccess&>);184static_assert(!std::is_invocable_v<RangeCDataT, BeginMemberRandomAccess&&>);185static_assert(!std::is_invocable_v<RangeCDataT, const BeginMemberRandomAccess&>);186static_assert(!std::is_invocable_v<RangeCDataT, const BeginMemberRandomAccess&&>);187 188struct BeginFriendContiguousIterator {189  int buff[8];190 191  friend constexpr ContiguousIter begin(const BeginFriendContiguousIterator &iter) {192    return ContiguousIter(iter.buff);193  }194};195static_assert( std::is_invocable_v<RangeDataT, BeginMemberContiguousIterator &>);196static_assert(!std::is_invocable_v<RangeDataT, BeginMemberContiguousIterator &&>);197static_assert( std::is_invocable_v<RangeDataT, BeginMemberContiguousIterator const&>);198static_assert(!std::is_invocable_v<RangeDataT, BeginMemberContiguousIterator const&&>);199static_assert( std::is_invocable_v<RangeCDataT, BeginMemberContiguousIterator &>);200static_assert(!std::is_invocable_v<RangeCDataT, BeginMemberContiguousIterator &&>);201static_assert( std::is_invocable_v<RangeCDataT, BeginMemberContiguousIterator const&>);202static_assert(!std::is_invocable_v<RangeCDataT, BeginMemberContiguousIterator const&&>);203 204struct BeginFriendRandomAccess {205  friend random_access_iterator<const int*> begin(const BeginFriendRandomAccess iter);206};207static_assert(!std::is_invocable_v<RangeDataT, BeginFriendRandomAccess&>);208static_assert(!std::is_invocable_v<RangeDataT, BeginFriendRandomAccess&&>);209static_assert(!std::is_invocable_v<RangeDataT, const BeginFriendRandomAccess&>);210static_assert(!std::is_invocable_v<RangeDataT, const BeginFriendRandomAccess&&>);211static_assert(!std::is_invocable_v<RangeCDataT, BeginFriendRandomAccess&>);212static_assert(!std::is_invocable_v<RangeCDataT, BeginFriendRandomAccess&&>);213static_assert(!std::is_invocable_v<RangeCDataT, const BeginFriendRandomAccess&>);214static_assert(!std::is_invocable_v<RangeCDataT, const BeginFriendRandomAccess&&>);215 216struct BeginMemberRvalue {217  int buff[8];218 219  ContiguousIter begin() &&;220};221static_assert(!std::is_invocable_v<RangeDataT, BeginMemberRvalue&>);222static_assert(!std::is_invocable_v<RangeDataT, BeginMemberRvalue&&>);223static_assert(!std::is_invocable_v<RangeDataT, BeginMemberRvalue const&>);224static_assert(!std::is_invocable_v<RangeDataT, BeginMemberRvalue const&&>);225static_assert(!std::is_invocable_v<RangeCDataT, BeginMemberRvalue&>);226static_assert(!std::is_invocable_v<RangeCDataT, BeginMemberRvalue&&>);227static_assert(!std::is_invocable_v<RangeCDataT, BeginMemberRvalue const&>);228static_assert(!std::is_invocable_v<RangeCDataT, BeginMemberRvalue const&&>);229 230struct BeginMemberBorrowingEnabled {231  constexpr contiguous_iterator<int*> begin() { return contiguous_iterator<int*>{&globalBuff[1]}; }232};233template<>234inline constexpr bool std::ranges::enable_borrowed_range<BeginMemberBorrowingEnabled> = true;235static_assert( std::is_invocable_v<RangeDataT, BeginMemberBorrowingEnabled &>);236static_assert( std::is_invocable_v<RangeDataT, BeginMemberBorrowingEnabled &&>);237static_assert(!std::is_invocable_v<RangeDataT, BeginMemberBorrowingEnabled const&>);238static_assert(!std::is_invocable_v<RangeDataT, BeginMemberBorrowingEnabled const&&>);239static_assert(!std::is_invocable_v<RangeCDataT, BeginMemberBorrowingEnabled &>);240static_assert(!std::is_invocable_v<RangeCDataT, BeginMemberBorrowingEnabled &&>);241static_assert(!std::is_invocable_v<RangeCDataT, BeginMemberBorrowingEnabled const&>);242static_assert(!std::is_invocable_v<RangeCDataT, BeginMemberBorrowingEnabled const&&>);243 244constexpr bool testViaRangesBegin() {245  int arr[2];246  assert(std::ranges::data(arr) == arr + 0);247  assert(std::ranges::cdata(arr) == arr + 0);248 249  BeginMemberContiguousIterator a;250  assert(std::ranges::data(a) == a.buff);251  assert(std::ranges::cdata(a) == a.buff);252 253  const BeginFriendContiguousIterator b {};254  assert(std::ranges::data(b) == b.buff);255  assert(std::ranges::cdata(b) == b.buff);256 257  BeginMemberBorrowingEnabled c;258  assert(std::ranges::data(std::move(c)) == &globalBuff[1]);259  static_assert(!std::is_invocable_v<RangeCDataT, decltype(std::move(c))>);260 261  return true;262}263 264// Test ADL-proofing.265struct Incomplete;266template<class T> struct Holder { T t; };267static_assert(!std::is_invocable_v<RangeDataT, Holder<Incomplete>*>);268static_assert(!std::is_invocable_v<RangeDataT, Holder<Incomplete>*&>);269static_assert(!std::is_invocable_v<RangeCDataT, Holder<Incomplete>*>);270static_assert(!std::is_invocable_v<RangeCDataT, Holder<Incomplete>*&>);271 272struct RandomButNotContiguous {273  random_access_iterator<int*> begin() const;274  random_access_iterator<int*> end() const;275};276static_assert(!std::is_invocable_v<RangeDataT, RandomButNotContiguous>);277static_assert(!std::is_invocable_v<RangeDataT, RandomButNotContiguous&>);278static_assert(!std::is_invocable_v<RangeCDataT, RandomButNotContiguous>);279static_assert(!std::is_invocable_v<RangeCDataT, RandomButNotContiguous&>);280 281int main(int, char**) {282  static_assert(testReturnTypes());283 284  testDataMember();285  static_assert(testDataMember());286 287  testViaRangesBegin();288  static_assert(testViaRangesBegin());289 290  return 0;291}292