xref: /aosp_15_r20/external/libchrome/base/containers/span_unittest.nc (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
1*635a8641SAndroid Build Coastguard Worker// Copyright 2017 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker// Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker// found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker
5*635a8641SAndroid Build Coastguard Worker// This is a "No Compile Test" suite.
6*635a8641SAndroid Build Coastguard Worker// http://dev.chromium.org/developers/testing/no-compile-tests
7*635a8641SAndroid Build Coastguard Worker
8*635a8641SAndroid Build Coastguard Worker#include "base/containers/span.h"
9*635a8641SAndroid Build Coastguard Worker
10*635a8641SAndroid Build Coastguard Worker#include <array>
11*635a8641SAndroid Build Coastguard Worker#include <set>
12*635a8641SAndroid Build Coastguard Worker#include <vector>
13*635a8641SAndroid Build Coastguard Worker
14*635a8641SAndroid Build Coastguard Workernamespace base {
15*635a8641SAndroid Build Coastguard Worker
16*635a8641SAndroid Build Coastguard Workerclass Base {
17*635a8641SAndroid Build Coastguard Worker};
18*635a8641SAndroid Build Coastguard Worker
19*635a8641SAndroid Build Coastguard Workerclass Derived : Base {
20*635a8641SAndroid Build Coastguard Worker};
21*635a8641SAndroid Build Coastguard Worker
22*635a8641SAndroid Build Coastguard Worker#if defined(NCTEST_DEFAULT_SPAN_WITH_NON_ZERO_STATIC_EXTENT_DISALLOWED)  // [r"fatal error: static_assert failed \"Invalid Extent\""]
23*635a8641SAndroid Build Coastguard Worker
24*635a8641SAndroid Build Coastguard Worker// A default constructed span must have an extent of 0 or dynamic_extent.
25*635a8641SAndroid Build Coastguard Workervoid WontCompile() {
26*635a8641SAndroid Build Coastguard Worker  span<int, 1> span;
27*635a8641SAndroid Build Coastguard Worker}
28*635a8641SAndroid Build Coastguard Worker
29*635a8641SAndroid Build Coastguard Worker#elif defined(NCTEST_SPAN_FROM_ARRAY_WITH_NON_MATCHING_STATIC_EXTENT_DISALLOWED) // [r"fatal error: no matching constructor for initialization of 'span<int, 1>'"]
30*635a8641SAndroid Build Coastguard Worker
31*635a8641SAndroid Build Coastguard Worker// A span with static extent constructed from an array must match the size of
32*635a8641SAndroid Build Coastguard Worker// the array.
33*635a8641SAndroid Build Coastguard Workervoid WontCompile() {
34*635a8641SAndroid Build Coastguard Worker  int array[] = {1, 2, 3};
35*635a8641SAndroid Build Coastguard Worker  span<int, 1> span(array);
36*635a8641SAndroid Build Coastguard Worker}
37*635a8641SAndroid Build Coastguard Worker
38*635a8641SAndroid Build Coastguard Worker#elif defined(NCTEST_SPAN_FROM_STD_ARRAY_WITH_NON_MATCHING_STATIC_EXTENT_DISALLOWED) // [r"fatal error: no matching constructor for initialization of 'span<int, 2>'"]
39*635a8641SAndroid Build Coastguard Worker
40*635a8641SAndroid Build Coastguard Worker// A span with static extent constructed from std::array must match the size of
41*635a8641SAndroid Build Coastguard Worker// the array.
42*635a8641SAndroid Build Coastguard Workervoid WontCompile() {
43*635a8641SAndroid Build Coastguard Worker  std::array<int, 3> array = {1, 2, 3};
44*635a8641SAndroid Build Coastguard Worker  span<int, 2> span(array);
45*635a8641SAndroid Build Coastguard Worker}
46*635a8641SAndroid Build Coastguard Worker
47*635a8641SAndroid Build Coastguard Worker#elif defined(NCTEST_SPAN_FROM_CONST_STD_ARRAY_WITH_NON_MATCHING_STATIC_EXTENT_DISALLOWED) // [r"fatal error: no matching constructor for initialization of 'span<const int, 2>'"]
48*635a8641SAndroid Build Coastguard Worker
49*635a8641SAndroid Build Coastguard Worker// A span with static extent constructed from std::array must match the size of
50*635a8641SAndroid Build Coastguard Worker// the array.
51*635a8641SAndroid Build Coastguard Workervoid WontCompile() {
52*635a8641SAndroid Build Coastguard Worker  const std::array<int, 3> array = {1, 2, 3};
53*635a8641SAndroid Build Coastguard Worker  span<const int, 2> span(array);
54*635a8641SAndroid Build Coastguard Worker}
55*635a8641SAndroid Build Coastguard Worker
56*635a8641SAndroid Build Coastguard Worker#elif defined(NCTEST_SPAN_FROM_OTHER_SPAN_WITH_MISMATCHING_EXTENT_DISALLOWED) // [r"fatal error: no matching constructor for initialization of 'span<int, 4>'"]
57*635a8641SAndroid Build Coastguard Worker
58*635a8641SAndroid Build Coastguard Worker// A span with static extent constructed from another span must match the
59*635a8641SAndroid Build Coastguard Worker// extent.
60*635a8641SAndroid Build Coastguard Workervoid WontCompile() {
61*635a8641SAndroid Build Coastguard Worker  std::array<int, 3> array = {1, 2, 3};
62*635a8641SAndroid Build Coastguard Worker  span<int, 3> span3(array);
63*635a8641SAndroid Build Coastguard Worker  span<int, 4> span4(span3);
64*635a8641SAndroid Build Coastguard Worker}
65*635a8641SAndroid Build Coastguard Worker
66*635a8641SAndroid Build Coastguard Worker#elif defined(NCTEST_DYNAMIC_SPAN_TO_STATIC_SPAN_DISALLOWED)  // [r"fatal error: no matching constructor for initialization of 'span<int, 3>'"]
67*635a8641SAndroid Build Coastguard Worker
68*635a8641SAndroid Build Coastguard Worker// Converting a dynamic span to a static span should not be allowed.
69*635a8641SAndroid Build Coastguard Workervoid WontCompile() {
70*635a8641SAndroid Build Coastguard Worker  span<int> dynamic_span;
71*635a8641SAndroid Build Coastguard Worker  span<int, 3> static_span(dynamic_span);
72*635a8641SAndroid Build Coastguard Worker}
73*635a8641SAndroid Build Coastguard Worker
74*635a8641SAndroid Build Coastguard Worker#elif defined(NCTEST_DERIVED_TO_BASE_CONVERSION_DISALLOWED)  // [r"fatal error: no matching constructor for initialization of 'span<base::Base \*>'"]
75*635a8641SAndroid Build Coastguard Worker
76*635a8641SAndroid Build Coastguard Worker// Internally, this is represented as a pointer to pointers to Derived. An
77*635a8641SAndroid Build Coastguard Worker// implicit conversion to a pointer to pointers to Base must not be allowed.
78*635a8641SAndroid Build Coastguard Worker// If it were allowed, then something like this would be possible.
79*635a8641SAndroid Build Coastguard Worker//   Cat** cats = GetCats();
80*635a8641SAndroid Build Coastguard Worker//   Animals** animals = cats;
81*635a8641SAndroid Build Coastguard Worker//   animals[0] = new Dog();  // Uhoh!
82*635a8641SAndroid Build Coastguard Workervoid WontCompile() {
83*635a8641SAndroid Build Coastguard Worker  span<Derived*> derived_span;
84*635a8641SAndroid Build Coastguard Worker  span<Base*> base_span(derived_span);
85*635a8641SAndroid Build Coastguard Worker}
86*635a8641SAndroid Build Coastguard Worker
87*635a8641SAndroid Build Coastguard Worker#elif defined(NCTEST_PTR_TO_CONSTPTR_CONVERSION_DISALLOWED)  // [r"fatal error: no matching constructor for initialization of 'span<const int \*>'"]
88*635a8641SAndroid Build Coastguard Worker
89*635a8641SAndroid Build Coastguard Worker// Similarly, converting a span<int*> to span<const int*> requires internally
90*635a8641SAndroid Build Coastguard Worker// converting T** to const T**. This is also disallowed, as it would allow code
91*635a8641SAndroid Build Coastguard Worker// to violate the contract of const.
92*635a8641SAndroid Build Coastguard Workervoid WontCompile() {
93*635a8641SAndroid Build Coastguard Worker  span<int*> non_const_span;
94*635a8641SAndroid Build Coastguard Worker  span<const int*> const_span(non_const_span);
95*635a8641SAndroid Build Coastguard Worker}
96*635a8641SAndroid Build Coastguard Worker
97*635a8641SAndroid Build Coastguard Worker#elif defined(NCTEST_CONST_CONTAINER_TO_MUTABLE_CONVERSION_DISALLOWED)  // [r"fatal error: no matching constructor for initialization of 'span<int>'"]
98*635a8641SAndroid Build Coastguard Worker
99*635a8641SAndroid Build Coastguard Worker// A const container should not be convertible to a mutable span.
100*635a8641SAndroid Build Coastguard Workervoid WontCompile() {
101*635a8641SAndroid Build Coastguard Worker  const std::vector<int> v = {1, 2, 3};
102*635a8641SAndroid Build Coastguard Worker  span<int> span(v);
103*635a8641SAndroid Build Coastguard Worker}
104*635a8641SAndroid Build Coastguard Worker
105*635a8641SAndroid Build Coastguard Worker#elif defined(NCTEST_STD_SET_CONVERSION_DISALLOWED)  // [r"fatal error: no matching constructor for initialization of 'span<int>'"]
106*635a8641SAndroid Build Coastguard Worker
107*635a8641SAndroid Build Coastguard Worker// A std::set() should not satisfy the requirements for conversion to a span.
108*635a8641SAndroid Build Coastguard Workervoid WontCompile() {
109*635a8641SAndroid Build Coastguard Worker  std::set<int> set;
110*635a8641SAndroid Build Coastguard Worker  span<int> span(set);
111*635a8641SAndroid Build Coastguard Worker}
112*635a8641SAndroid Build Coastguard Worker
113*635a8641SAndroid Build Coastguard Worker#elif defined(NCTEST_STATIC_FRONT_WITH_EXCEEDING_COUNT_DISALLOWED)  // [r"fatal error: static_assert failed \"Count must not exceed Extent\""]
114*635a8641SAndroid Build Coastguard Worker
115*635a8641SAndroid Build Coastguard Worker// Static first called on a span with static extent must not exceed the size.
116*635a8641SAndroid Build Coastguard Workervoid WontCompile() {
117*635a8641SAndroid Build Coastguard Worker  std::array<int, 3> array = {1, 2, 3};
118*635a8641SAndroid Build Coastguard Worker  span<int, 3> span(array);
119*635a8641SAndroid Build Coastguard Worker  auto first = span.first<4>();
120*635a8641SAndroid Build Coastguard Worker}
121*635a8641SAndroid Build Coastguard Worker
122*635a8641SAndroid Build Coastguard Worker#elif defined(NCTEST_STATIC_LAST_WITH_EXCEEDING_COUNT_DISALLOWED)  // [r"fatal error: static_assert failed \"Count must not exceed Extent\""]
123*635a8641SAndroid Build Coastguard Worker
124*635a8641SAndroid Build Coastguard Worker// Static last called on a span with static extent must not exceed the size.
125*635a8641SAndroid Build Coastguard Workervoid WontCompile() {
126*635a8641SAndroid Build Coastguard Worker  std::array<int, 3> array = {1, 2, 3};
127*635a8641SAndroid Build Coastguard Worker  span<int, 3> span(array);
128*635a8641SAndroid Build Coastguard Worker  auto last = span.last<4>();
129*635a8641SAndroid Build Coastguard Worker}
130*635a8641SAndroid Build Coastguard Worker
131*635a8641SAndroid Build Coastguard Worker#elif defined(NCTEST_STATIC_SUBSPAN_WITH_EXCEEDING_OFFSET_DISALLOWED)  // [r"fatal error: static_assert failed \"Offset must not exceed Extent\""]
132*635a8641SAndroid Build Coastguard Worker
133*635a8641SAndroid Build Coastguard Worker// Static subspan called on a span with static extent must not exceed the size.
134*635a8641SAndroid Build Coastguard Workervoid WontCompile() {
135*635a8641SAndroid Build Coastguard Worker  std::array<int, 3> array = {1, 2, 3};
136*635a8641SAndroid Build Coastguard Worker  span<int, 3> span(array);
137*635a8641SAndroid Build Coastguard Worker  auto subspan = span.subspan<4>();
138*635a8641SAndroid Build Coastguard Worker}
139*635a8641SAndroid Build Coastguard Worker
140*635a8641SAndroid Build Coastguard Worker#elif defined(NCTEST_STATIC_SUBSPAN_WITH_EXCEEDING_COUNT_DISALLOWED)  // [r"fatal error: static_assert failed \"Count must not exceed Extent - Offset\""]
141*635a8641SAndroid Build Coastguard Worker
142*635a8641SAndroid Build Coastguard Worker// Static subspan called on a span with static extent must not exceed the size.
143*635a8641SAndroid Build Coastguard Workervoid WontCompile() {
144*635a8641SAndroid Build Coastguard Worker  std::array<int, 3> array = {1, 2, 3};
145*635a8641SAndroid Build Coastguard Worker  span<int, 3> span(array);
146*635a8641SAndroid Build Coastguard Worker  auto subspan = span.subspan<0, 4>();
147*635a8641SAndroid Build Coastguard Worker}
148*635a8641SAndroid Build Coastguard Worker
149*635a8641SAndroid Build Coastguard Worker#elif defined(NCTEST_AS_WRITABLE_BYTES_WITH_CONST_CONTAINER_DISALLOWED)  // [r"fatal error: no matching function for call to 'as_writable_bytes'"]
150*635a8641SAndroid Build Coastguard Worker
151*635a8641SAndroid Build Coastguard Worker// as_writable_bytes should not be possible for a const container.
152*635a8641SAndroid Build Coastguard Workervoid WontCompile() {
153*635a8641SAndroid Build Coastguard Worker  const std::vector<int> v = {1, 2, 3};
154*635a8641SAndroid Build Coastguard Worker  span<uint8_t> bytes = as_writable_bytes(make_span(v));
155*635a8641SAndroid Build Coastguard Worker}
156*635a8641SAndroid Build Coastguard Worker
157*635a8641SAndroid Build Coastguard Worker#elif defined(NCTEST_MAKE_SPAN_FROM_SET_CONVERSION_DISALLOWED)  // [r"fatal error: no matching function for call to 'make_span'"]
158*635a8641SAndroid Build Coastguard Worker
159*635a8641SAndroid Build Coastguard Worker// A std::set() should not satisfy the requirements for conversion to a span.
160*635a8641SAndroid Build Coastguard Workervoid WontCompile() {
161*635a8641SAndroid Build Coastguard Worker  std::set<int> set;
162*635a8641SAndroid Build Coastguard Worker  auto span = make_span(set);
163*635a8641SAndroid Build Coastguard Worker}
164*635a8641SAndroid Build Coastguard Worker
165*635a8641SAndroid Build Coastguard Worker#endif
166*635a8641SAndroid Build Coastguard Worker
167*635a8641SAndroid Build Coastguard Worker}  // namespace base
168