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