/////////////////////////////////////////////////////////////////////////////// // // Copyright (c) 2015 Microsoft Corporation. All rights reserved. // // This code is licensed under the MIT License (MIT). // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // /////////////////////////////////////////////////////////////////////////////// #include #include // for byte #include // for span, span_iterator, operator==, operator!= #include // for array #include // for ptrdiff_t #include // for reverse_iterator, operator-, operator== #include // for integral_constant<>::value, is_default_co... #include #include // for vector using namespace std; using namespace gsl; // Below are tests that verify the gsl interface support the same things as the std // Ranges and Concepts support need to be added later. struct Base { }; struct Derived : Base { }; static_assert(std::is_convertible::value, "std::is_convertible"); static_assert(!std::is_convertible::value, "!std::is_convertible"); // int*(*) [], int const* const(*)[] was identified as an issue in CWG330 and the resolution was // provided with N4261. template void ArrayConvertibilityCheck() { #if __cplusplus >= 201703l if constexpr (std::is_convertible::value) { std::array stl_nullptr{{nullptr, nullptr, nullptr}}; gsl::span sp_const_nullptr_1{stl_nullptr}; EXPECT_TRUE(sp_const_nullptr_1.data() == stl_nullptr.data()); EXPECT_TRUE(sp_const_nullptr_1.size() == 3); span sp_const_nullptr_2{std::as_const(stl_nullptr)}; EXPECT_TRUE(sp_const_nullptr_2.data() == stl_nullptr.data()); EXPECT_TRUE(sp_const_nullptr_2.size() == 3); static_assert(std::is_same>::value, "std::is_same< decltype(span{stl_nullptr}), span>::value"); static_assert( std::is_same>::value, "std::is_same< decltype(span{std::as_const(stl_nullptr)}), span>::value"); } #endif } TEST(span_compatibility_tests, assertion_tests) { int arr[3]{10, 20, 30}; std::array stl{{100, 200, 300}}; ArrayConvertibilityCheck(); { gsl::span sp_dyn; EXPECT_TRUE(sp_dyn.data() == nullptr); EXPECT_TRUE(sp_dyn.size() == 0); EXPECT_TRUE(sp_dyn.empty()); } { gsl::span sp_zero; EXPECT_TRUE(sp_zero.data() == nullptr); EXPECT_TRUE(sp_zero.size() == 0); EXPECT_TRUE(sp_zero.empty()); gsl::span sp_dyn_a(arr, 3); gsl::span sp_dyn_b(begin(arr), 3); EXPECT_TRUE(sp_dyn_a.data() == std::begin(arr)); EXPECT_TRUE(sp_dyn_b.data() == std::begin(arr)); EXPECT_TRUE(sp_dyn_a.size() == 3); EXPECT_TRUE(sp_dyn_b.size() == 3); gsl::span sp_three_a(arr, 3); gsl::span sp_three_b(begin(arr), 3); EXPECT_TRUE(sp_three_a.data() == std::begin(arr)); EXPECT_TRUE(sp_three_b.data() == std::begin(arr)); EXPECT_TRUE(sp_three_a.size() == 3); EXPECT_TRUE(sp_three_b.size() == 3); gsl::span sp_const_a(arr, 3); gsl::span sp_const_b(begin(arr), 3); EXPECT_TRUE(sp_const_a.data() == std::begin(arr)); EXPECT_TRUE(sp_const_b.data() == std::begin(arr)); EXPECT_TRUE(sp_const_a.size() == 3); EXPECT_TRUE(sp_const_b.size() == 3); #if __cplusplus >= 201703l gsl::span sp_const_c(std::as_const(arr), 3); EXPECT_TRUE(sp_const_c.data() == std::begin(arr)); EXPECT_TRUE(sp_const_c.size() == 3); #endif // __cplusplus >= 201703l gsl::span sp_const_d(cbegin(arr), 3); EXPECT_TRUE(sp_const_d.data() == std::begin(arr)); EXPECT_TRUE(sp_const_d.size() == 3); } { gsl::span sp_dyn_a(begin(arr), std::end(arr)); EXPECT_TRUE(sp_dyn_a.data() == std::begin(arr)); EXPECT_TRUE(sp_dyn_a.size() == 3); gsl::span sp_three_a(begin(arr), std::end(arr)); EXPECT_TRUE(sp_three_a.data() == std::begin(arr)); EXPECT_TRUE(sp_three_a.size() == 3); gsl::span sp_const_a(begin(arr), std::end(arr)); gsl::span sp_const_b(begin(arr), std::cend(arr)); gsl::span sp_const_c(cbegin(arr), std::end(arr)); gsl::span sp_const_d(cbegin(arr), std::cend(arr)); EXPECT_TRUE(sp_const_a.data() == std::begin(arr)); EXPECT_TRUE(sp_const_b.data() == std::begin(arr)); EXPECT_TRUE(sp_const_c.data() == std::begin(arr)); EXPECT_TRUE(sp_const_d.data() == std::begin(arr)); EXPECT_TRUE(sp_const_a.size() == 3); EXPECT_TRUE(sp_const_b.size() == 3); EXPECT_TRUE(sp_const_c.size() == 3); EXPECT_TRUE(sp_const_d.size() == 3); } { gsl::span sp_dyn_a(arr); gsl::span sp_dyn_b(stl); gsl::span sp_dyn_c{stl}; gsl::span sp_dyn_d{stl}; EXPECT_TRUE(sp_dyn_a.data() == std::begin(arr)); EXPECT_TRUE(sp_dyn_b.data() == stl.data()); EXPECT_TRUE(sp_dyn_a.size() == 3); EXPECT_TRUE(sp_dyn_b.size() == 3); gsl::span sp_three_a(arr); gsl::span sp_three_b(stl); EXPECT_TRUE(sp_three_a.data() == std::begin(arr)); EXPECT_TRUE(sp_three_b.data() == stl.data()); EXPECT_TRUE(sp_three_a.size() == 3); EXPECT_TRUE(sp_three_b.size() == 3); gsl::span sp_const_w(arr); gsl::span sp_const_y(stl); EXPECT_TRUE(sp_const_w.data() == std::begin(arr)); EXPECT_TRUE(sp_const_y.data() == stl.data()); EXPECT_TRUE(sp_const_w.size() == 3); EXPECT_TRUE(sp_const_y.size() == 3); #if __cplusplus >= 201703l gsl::span sp_const_x(std::as_const(arr)); EXPECT_TRUE(sp_const_x.data() == std::begin(arr)); EXPECT_TRUE(sp_const_x.size() == 3); gsl::span sp_const_z(std::as_const(stl)); EXPECT_TRUE(sp_const_z.data() == stl.data()); EXPECT_TRUE(sp_const_z.size() == 3); #endif // __cplusplus >= 201703l } { const gsl::span orig_dyn(arr); const gsl::span orig_three(arr); const gsl::span orig_const_dyn(arr); const gsl::span orig_const_three(arr); gsl::span sp_a(orig_dyn); gsl::span sp_b(orig_three); gsl::span sp_c(orig_three); gsl::span sp_d(orig_dyn); gsl::span sp_e(orig_three); gsl::span sp_f(orig_const_dyn); gsl::span sp_g(orig_const_three); gsl::span sp_h(orig_three); gsl::span sp_i(orig_const_three); EXPECT_TRUE(sp_a.data() == std::begin(arr)); EXPECT_TRUE(sp_b.data() == std::begin(arr)); EXPECT_TRUE(sp_c.data() == std::begin(arr)); EXPECT_TRUE(sp_d.data() == std::begin(arr)); EXPECT_TRUE(sp_e.data() == std::begin(arr)); EXPECT_TRUE(sp_f.data() == std::begin(arr)); EXPECT_TRUE(sp_g.data() == std::begin(arr)); EXPECT_TRUE(sp_h.data() == std::begin(arr)); EXPECT_TRUE(sp_i.data() == std::begin(arr)); EXPECT_TRUE(sp_a.size() == 3); EXPECT_TRUE(sp_b.size() == 3); EXPECT_TRUE(sp_c.size() == 3); EXPECT_TRUE(sp_d.size() == 3); EXPECT_TRUE(sp_e.size() == 3); EXPECT_TRUE(sp_f.size() == 3); EXPECT_TRUE(sp_g.size() == 3); EXPECT_TRUE(sp_h.size() == 3); EXPECT_TRUE(sp_i.size() == 3); } { gsl::span sp_dyn(arr); gsl::span sp_three(arr); gsl::span sp_const_dyn(arr); gsl::span sp_const_three(arr); EXPECT_TRUE(sp_dyn.data() == std::begin(arr)); EXPECT_TRUE(sp_three.data() == std::begin(arr)); EXPECT_TRUE(sp_const_dyn.data() == std::begin(arr)); EXPECT_TRUE(sp_const_three.data() == std::begin(arr)); EXPECT_TRUE(sp_dyn.size() == 3); EXPECT_TRUE(sp_three.size() == 3); EXPECT_TRUE(sp_const_dyn.size() == 3); EXPECT_TRUE(sp_const_three.size() == 3); int other[4]{12, 34, 56, 78}; sp_dyn = gsl::span{other}; sp_three = gsl::span{stl}; sp_const_dyn = gsl::span{other}; sp_const_three = gsl::span{stl}; EXPECT_TRUE(sp_dyn.data() == std::begin(other)); EXPECT_TRUE(sp_three.data() == stl.data()); EXPECT_TRUE(sp_const_dyn.data() == std::begin(other)); EXPECT_TRUE(sp_const_three.data() == stl.data()); EXPECT_TRUE(sp_dyn.size() == 4); EXPECT_TRUE(sp_three.size() == 3); EXPECT_TRUE(sp_const_dyn.size() == 4); EXPECT_TRUE(sp_const_three.size() == 3); } { gsl::span::iterator it_dyn{}; { gsl::span sp_dyn(arr); it_dyn = sp_dyn.begin(); } EXPECT_TRUE(*it_dyn == arr[0]); EXPECT_TRUE(it_dyn[2] == arr[2]); gsl::span::iterator it_three{}; { gsl::span sp_three(stl); it_three = sp_three.begin(); } EXPECT_TRUE(*it_three == stl[0]); EXPECT_TRUE(it_three[2] == stl[2]); } { int sequence[9]{10, 20, 30, 40, 50, 60, 70, 80, 90}; const gsl::span sp_dyn(sequence); const gsl::span sp_nine(sequence); auto first_3 = sp_dyn.first<3>(); auto first_4 = sp_nine.first<4>(); auto first_5 = sp_dyn.first(5); auto first_6 = sp_nine.first(6); static_assert(noexcept(sp_dyn.first<3>()), "noexcept(sp_dyn.first<3>())"); // strengthened static_assert(noexcept(sp_nine.first<4>()), "noexcept(sp_nine.first<4>())"); // strengthened static_assert(noexcept(sp_dyn.first(5)), "noexcept(sp_dyn.first(5))"); // strengthened static_assert(noexcept(sp_nine.first(6)), "noexcept(sp_nine.first(6))"); // strengthened static_assert(is_same>::value, "is_same>::value"); static_assert(is_same>::value, "is_same>::value"); static_assert(is_same>::value, "is_same>::value"); static_assert(is_same>::value, "is_same>::value"); EXPECT_TRUE(first_3.data() == std::begin(sequence)); EXPECT_TRUE(first_4.data() == std::begin(sequence)); EXPECT_TRUE(first_5.data() == std::begin(sequence)); EXPECT_TRUE(first_6.data() == std::begin(sequence)); EXPECT_TRUE(first_3.size() == 3); EXPECT_TRUE(first_4.size() == 4); EXPECT_TRUE(first_5.size() == 5); EXPECT_TRUE(first_6.size() == 6); auto last_3 = sp_dyn.last<3>(); auto last_4 = sp_nine.last<4>(); auto last_5 = sp_dyn.last(5); auto last_6 = sp_nine.last(6); static_assert(noexcept(sp_dyn.last<3>()), "noexcept(sp_dyn.last<3>())"); // strengthened static_assert(noexcept(sp_nine.last<4>()), "noexcept(sp_nine.last<4>())"); // strengthened static_assert(noexcept(sp_dyn.last(5)), "noexcept(sp_dyn.last(5))"); // strengthened static_assert(noexcept(sp_nine.last(6)), "noexcept(sp_nine.last(6))"); // strengthened static_assert(is_same>::value, "is_same>::value"); static_assert(is_same>::value, "is_same>::value"); static_assert(is_same>::value, "is_same>::value"); static_assert(is_same>::value, "is_same>::value"); EXPECT_TRUE(last_3.data() == std::begin(sequence) + 6); EXPECT_TRUE(last_4.data() == std::begin(sequence) + 5); EXPECT_TRUE(last_5.data() == std::begin(sequence) + 4); EXPECT_TRUE(last_6.data() == std::begin(sequence) + 3); EXPECT_TRUE(last_3.size() == 3); EXPECT_TRUE(last_4.size() == 4); EXPECT_TRUE(last_5.size() == 5); EXPECT_TRUE(last_6.size() == 6); auto offset_3 = sp_dyn.subspan<3>(); auto offset_4 = sp_nine.subspan<4>(); auto offset_5 = sp_dyn.subspan(5); auto offset_6 = sp_nine.subspan(6); static_assert(noexcept(sp_dyn.subspan<3>()), "noexcept(sp_dyn.subspan<3>())"); // strengthened static_assert(noexcept(sp_nine.subspan<4>()), "noexcept(sp_nine.subspan<4>())"); // strengthened static_assert(noexcept(sp_dyn.subspan(5)), "noexcept(sp_dyn.subspan(5))"); // strengthened static_assert(noexcept(sp_nine.subspan(6)), "noexcept(sp_nine.subspan(6))"); // strengthened static_assert(is_same>::value, "is_same>::value"); static_assert(is_same>::value, "is_same>::value"); static_assert(is_same>::value, "is_same>::value"); static_assert(is_same>::value, "is_same>::value"); EXPECT_TRUE(offset_3.data() == std::begin(sequence) + 3); EXPECT_TRUE(offset_4.data() == std::begin(sequence) + 4); EXPECT_TRUE(offset_5.data() == std::begin(sequence) + 5); EXPECT_TRUE(offset_6.data() == std::begin(sequence) + 6); EXPECT_TRUE(offset_3.size() == 6); EXPECT_TRUE(offset_4.size() == 5); EXPECT_TRUE(offset_5.size() == 4); EXPECT_TRUE(offset_6.size() == 3); auto subspan_3 = sp_dyn.subspan<3, 2>(); auto subspan_4 = sp_nine.subspan<4, 2>(); auto subspan_5 = sp_dyn.subspan(5, 2); auto subspan_6 = sp_nine.subspan(6, 2); static_assert(noexcept(sp_dyn.subspan<3, 2>()), "noexcept(sp_dyn.subspan<3, 2>())"); // strengthened static_assert(noexcept(sp_nine.subspan<4, 2>()), "noexcept(sp_nine.subspan<4, 2>())"); // strengthened static_assert(noexcept(sp_dyn.subspan(5, 2)), "noexcept(sp_dyn.subspan(5, 2))"); // strengthened static_assert(noexcept(sp_nine.subspan(6, 2)), "noexcept(sp_nine.subspan(6, 2))"); // strengthened static_assert(is_same>::value, "is_same>::value"); static_assert(is_same>::value, "is_same>::value"); static_assert(is_same>::value, "is_same>::value"); static_assert(is_same>::value, "is_same>::value"); EXPECT_TRUE(subspan_3.data() == std::begin(sequence) + 3); EXPECT_TRUE(subspan_4.data() == std::begin(sequence) + 4); EXPECT_TRUE(subspan_5.data() == std::begin(sequence) + 5); EXPECT_TRUE(subspan_6.data() == std::begin(sequence) + 6); EXPECT_TRUE(subspan_3.size() == 2); EXPECT_TRUE(subspan_4.size() == 2); EXPECT_TRUE(subspan_5.size() == 2); EXPECT_TRUE(subspan_6.size() == 2); static_assert(noexcept(sp_dyn.size()), "noexcept(sp_dyn.size())"); static_assert(noexcept(sp_dyn.size_bytes()), "noexcept(sp_dyn.size_bytes())"); static_assert(noexcept(sp_dyn.empty()), "noexcept(sp_dyn.empty())"); static_assert(noexcept(sp_dyn[0]), "noexcept(sp_dyn[0])"); // strengthened static_assert(noexcept(sp_dyn.front()), "noexcept(sp_dyn.front())"); // strengthened static_assert(noexcept(sp_dyn.back()), "noexcept(sp_dyn.back())"); // strengthened static_assert(noexcept(sp_dyn.data()), "noexcept(sp_dyn.data())"); static_assert(noexcept(sp_dyn.begin()), "noexcept(sp_dyn.begin())"); static_assert(noexcept(sp_dyn.end()), "noexcept(sp_dyn.end())"); static_assert(noexcept(sp_dyn.cbegin()), "noexcept(sp_dyn.cbegin())"); static_assert(noexcept(sp_dyn.cend()), "noexcept(sp_dyn.cend())"); static_assert(noexcept(sp_dyn.rbegin()), "noexcept(sp_dyn.rbegin())"); static_assert(noexcept(sp_dyn.rend()), "noexcept(sp_dyn.rend())"); static_assert(noexcept(sp_dyn.crbegin()), "noexcept(sp_dyn.crbegin())"); static_assert(noexcept(sp_dyn.crend()), "noexcept(sp_dyn.crend())"); static_assert(noexcept(sp_nine.size()), "noexcept(sp_nine.size())"); static_assert(noexcept(sp_nine.size_bytes()), "noexcept(sp_nine.size_bytes())"); static_assert(noexcept(sp_nine.empty()), "noexcept(sp_nine.empty())"); static_assert(noexcept(sp_nine[0]), "noexcept(sp_nine[0])"); // strengthened static_assert(noexcept(sp_nine.front()), "noexcept(sp_nine.front())"); // strengthened static_assert(noexcept(sp_nine.back()), "noexcept(sp_nine.back())"); // strengthened static_assert(noexcept(sp_nine.data()), "noexcept(sp_nine.data())"); static_assert(noexcept(sp_nine.begin()), "noexcept(sp_nine.begin())"); static_assert(noexcept(sp_nine.end()), "noexcept(sp_nine.end())"); static_assert(noexcept(sp_nine.cbegin()), "noexcept(sp_nine.cbegin())"); static_assert(noexcept(sp_nine.cend()), "noexcept(sp_nine.cend())"); static_assert(noexcept(sp_nine.rbegin()), "noexcept(sp_nine.rbegin())"); static_assert(noexcept(sp_nine.rend()), "noexcept(sp_nine.rend())"); static_assert(noexcept(sp_nine.crbegin()), "noexcept(sp_nine.crbegin())"); static_assert(noexcept(sp_nine.crend()), "noexcept(sp_nine.crend())"); EXPECT_TRUE(sp_dyn.size() == 9); EXPECT_TRUE(sp_nine.size() == 9); EXPECT_TRUE(sp_dyn.size_bytes() == 9 * sizeof(int)); EXPECT_TRUE(sp_nine.size_bytes() == 9 * sizeof(int)); EXPECT_TRUE(!sp_dyn.empty()); EXPECT_TRUE(!sp_nine.empty()); EXPECT_TRUE(sp_dyn[0] == 10); EXPECT_TRUE(sp_nine[0] == 10); EXPECT_TRUE(sp_dyn[8] == 90); EXPECT_TRUE(sp_nine[8] == 90); EXPECT_TRUE(sp_dyn.front() == 10); EXPECT_TRUE(sp_nine.front() == 10); EXPECT_TRUE(sp_dyn.back() == 90); EXPECT_TRUE(sp_nine.back() == 90); EXPECT_TRUE(&sp_dyn.front() == std::begin(sequence)); EXPECT_TRUE(&sp_nine.front() == std::begin(sequence)); EXPECT_TRUE(&sp_dyn[4] == std::begin(sequence) + 4); EXPECT_TRUE(&sp_nine[4] == std::begin(sequence) + 4); EXPECT_TRUE(&sp_dyn.back() == std::begin(sequence) + 8); EXPECT_TRUE(&sp_nine.back() == std::begin(sequence) + 8); EXPECT_TRUE(sp_dyn.data() == std::begin(sequence)); EXPECT_TRUE(sp_nine.data() == std::begin(sequence)); EXPECT_TRUE(*sp_dyn.begin() == 10); EXPECT_TRUE(*sp_nine.begin() == 10); EXPECT_TRUE(sp_dyn.end()[-2] == 80); EXPECT_TRUE(sp_nine.end()[-2] == 80); EXPECT_TRUE(*sp_dyn.cbegin() == 10); EXPECT_TRUE(*sp_nine.cbegin() == 10); EXPECT_TRUE(sp_dyn.cend()[-2] == 80); EXPECT_TRUE(sp_nine.cend()[-2] == 80); EXPECT_TRUE(*sp_dyn.rbegin() == 90); EXPECT_TRUE(*sp_nine.rbegin() == 90); EXPECT_TRUE(sp_dyn.rend()[-2] == 20); EXPECT_TRUE(sp_nine.rend()[-2] == 20); EXPECT_TRUE(*sp_dyn.crbegin() == 90); EXPECT_TRUE(*sp_nine.crbegin() == 90); EXPECT_TRUE(sp_dyn.crend()[-2] == 20); EXPECT_TRUE(sp_nine.crend()[-2] == 20); static_assert(is_same::iterator>::value, "is_same::iterator>::value"); static_assert(is_same::iterator>::value, "is_same::iterator>::value"); static_assert(is_same::iterator>::value, "is_same::iterator>::value"); static_assert(is_same::iterator>::value, "is_same::iterator>::value"); static_assert(is_same::const_iterator>::value, "is_same::const_iterator>::value"); static_assert( is_same::const_iterator>::value, "is_same::const_iterator>::value"); static_assert(is_same::const_iterator>::value, "is_same::const_iterator>::value"); static_assert( is_same::const_iterator>::value, "is_same::const_iterator>::value"); static_assert( is_same::reverse_iterator>::value, "is_same::reverse_iterator>::value"); static_assert( is_same::reverse_iterator>::value, "is_same::reverse_iterator>::value"); static_assert(is_same::reverse_iterator>::value, "is_same::reverse_iterator>::value"); static_assert( is_same::reverse_iterator>::value, "is_same::reverse_iterator>::value"); static_assert( is_same::const_reverse_iterator>::value, "is_same::const_reverse_iterator>::value"); static_assert( is_same::const_reverse_iterator>::value, "is_same::const_reverse_iterator>::value"); static_assert( is_same::const_reverse_iterator>::value, "is_same::const_reverse_iterator>::value"); static_assert( is_same::const_reverse_iterator>::value, "is_same::const_reverse_iterator>::value"); } { int sequence[9]{10, 20, 30, 40, 50, 60, 70, 80, 90}; constexpr size_t SizeBytes = sizeof(sequence); const gsl::span sp_dyn(sequence); const gsl::span sp_nine(sequence); const gsl::span sp_const_dyn(sequence); const gsl::span sp_const_nine(sequence); static_assert(noexcept(as_bytes(sp_dyn)), "noexcept(as_bytes(sp_dyn))"); static_assert(noexcept(as_bytes(sp_nine)), "noexcept(as_bytes(sp_nine))"); static_assert(noexcept(as_bytes(sp_const_dyn)), "noexcept(as_bytes(sp_const_dyn))"); static_assert(noexcept(as_bytes(sp_const_nine)), "noexcept(as_bytes(sp_const_nine))"); static_assert(noexcept(as_writable_bytes(sp_dyn)), "noexcept(as_writable_bytes(sp_dyn))"); static_assert(noexcept(as_writable_bytes(sp_nine)), "noexcept(as_writable_bytes(sp_nine))"); auto sp_1 = as_bytes(sp_dyn); auto sp_2 = as_bytes(sp_nine); auto sp_3 = as_bytes(sp_const_dyn); auto sp_4 = as_bytes(sp_const_nine); auto sp_5 = as_writable_bytes(sp_dyn); auto sp_6 = as_writable_bytes(sp_nine); static_assert(is_same>::value, "is_same>::value"); static_assert(is_same>::value, "is_same>::value"); static_assert(is_same>::value, "is_same>::value"); static_assert(is_same>::value, "is_same>::value"); static_assert(is_same>::value, "is_same>::value"); static_assert(is_same>::value, "is_same>::value"); EXPECT_TRUE(sp_1.data() == reinterpret_cast(begin(sequence))); EXPECT_TRUE(sp_2.data() == reinterpret_cast(begin(sequence))); EXPECT_TRUE(sp_3.data() == reinterpret_cast(begin(sequence))); EXPECT_TRUE(sp_4.data() == reinterpret_cast(begin(sequence))); EXPECT_TRUE(sp_5.data() == reinterpret_cast(begin(sequence))); EXPECT_TRUE(sp_6.data() == reinterpret_cast(begin(sequence))); EXPECT_TRUE(sp_1.size() == SizeBytes); EXPECT_TRUE(sp_2.size() == SizeBytes); EXPECT_TRUE(sp_3.size() == SizeBytes); EXPECT_TRUE(sp_4.size() == SizeBytes); EXPECT_TRUE(sp_5.size() == SizeBytes); EXPECT_TRUE(sp_6.size() == SizeBytes); } } // assertions for span's definition static_assert(std::is_same::value, "gsl::dynamic_extent must be respresented as std::size_t"); static_assert(gsl::dynamic_extent == static_cast(-1), "gsl::dynamic_extent must be defined as the max value of std::size_t"); static_assert(std::is_same::extent), const std::size_t>::value, "Ensure that the type of gsl::span::extent is std::size_t"); static_assert(gsl::span::extent == gsl::dynamic_extent, "gsl::span::extent should be equivalent to gsl::dynamic_extent"); static_assert(std::is_same::extent), const std::size_t>::value, "Ensure that the type of gsl::span::extent is std::size_t"); static_assert(gsl::span::extent == 3, "Ensure that span::extent is equal to 3"); static_assert(std::is_same::element_type, int>::value, "span::element_type should be int"); static_assert(std::is_same::value_type, int>::value, "span::value_type should be int"); static_assert(std::is_same::size_type, std::size_t>::value, "span::size_type should be std::size_t"); static_assert(std::is_same::difference_type, ptrdiff_t>::value, "span::difference_type should be std::ptrdiff_t"); static_assert(std::is_same::pointer, int*>::value, "span::pointer should be int*"); static_assert(std::is_same::const_pointer, const int*>::value, "span::const_pointer should be const int*"); static_assert(std::is_same::reference, int&>::value, "span::reference should be int&"); static_assert(std::is_same::const_reference, const int&>::value, "span::const_reference should be const int&"); static_assert(std::is_same::element_type, int>::value, "span::element_type should be int"); static_assert(std::is_same::value_type, int>::value, "span::value_type should be int"); static_assert(std::is_same::size_type, std::size_t>::value, "span::size_type should be std::size_t"); static_assert(std::is_same::difference_type, ptrdiff_t>::value, "span::difference_type should be std::ptrdiff_t"); static_assert(std::is_same::pointer, int*>::value, "span::pointer should be int*"); static_assert(std::is_same::const_pointer, const int*>::value, "span::const_pointer should be const int*"); static_assert(std::is_same::reference, int&>::value, "span::reference should be int&"); static_assert(std::is_same::const_reference, const int&>::value, "span::const_reference should be const int&"); static_assert(std::is_same::element_type, const int>::value, "span::element_type should be const int"); static_assert(std::is_same::value_type, int>::value, "span::value_type should be int"); static_assert(std::is_same::size_type, std::size_t>::value, "span::size_type should be size_t"); static_assert(std::is_same::difference_type, ptrdiff_t>::value, "span::difference_type should be ptrdiff_t"); static_assert(std::is_same::pointer, const int*>::value, "span::pointer should be const int*"); static_assert(std::is_same::const_pointer, const int*>::value, "span::const_pointer should be const int*"); static_assert(std::is_same::reference, const int&>::value, "span::reference should be const int&"); static_assert(std::is_same::const_reference, const int&>::value, "span::const_reference should be const int&"); static_assert(std::is_same::element_type, const int>::value, "span::element_type should be const int"); static_assert(std::is_same::value_type, int>::value, "span::value_type should be int"); static_assert(std::is_same::size_type, std::size_t>::value, "span::size_type should be size_t"); static_assert(std::is_same::difference_type, ptrdiff_t>::value, "span::difference_type should be ptrdiff_t"); static_assert(std::is_same::pointer, const int*>::value, "span::pointer should be const int*"); static_assert(std::is_same::const_pointer, const int*>::value, "span::const_pointer should be const int*"); static_assert(std::is_same::reference, const int&>::value, "span::reference should be const int&"); static_assert(std::is_same::const_reference, const int&>::value, "span::const_reference should be const int&"); // assertions for span_iterator static_assert(std::is_same::iterator>::pointer, int*>::value, "span::iterator's pointer should be int*"); static_assert( std::is_same::const_iterator>::pointer, const int*>::value, "span::const_iterator's pointer should be const int*"); static_assert( std::is_same::reverse_iterator, std::reverse_iterator::iterator>>::value, "span::reverse_iterator should equal std::reverse_iterator::iterator>"); static_assert(std::is_same::const_reverse_iterator, std::reverse_iterator::const_iterator>>::value, "span::const_reverse_iterator should equal " "std::reverse_iterator::const_iterator>"); static_assert(std::is_same::iterator>::pointer, int*>::value, "span::iterator's pointer should be int*"); static_assert(std::is_same::const_iterator>::pointer, const int*>::value, "span::const_iterator's pointer should be const int*"); static_assert( std::is_same::reverse_iterator, std::reverse_iterator::iterator>>::value, "span::reverse_iterator should equal std::reverse_iterator::iterator>"); static_assert(std::is_same::const_reverse_iterator, std::reverse_iterator::const_iterator>>::value, "span::const_reverse_iterator should equal std::reverse_iterator::const_iterator>"); static_assert( std::is_same::iterator>::pointer, const int*>::value, "span::iterator's pointer should be int*"); static_assert(std::is_same::const_iterator>::pointer, const int*>::value, "span::const_iterator's pointer should be const int*"); static_assert(std::is_same::reverse_iterator, std::reverse_iterator::iterator>>::value, "span::reverse_iterator should equal std::reverse_iterator::iterator>"); static_assert(std::is_same::const_reverse_iterator, std::reverse_iterator::const_iterator>>::value, "span::const_reverse_iterator should equal " "std::reverse_iterator::const_iterator>"); static_assert(std::is_same::iterator>::pointer, const int*>::value, "span::iterator's pointer should be int*"); static_assert(std::is_same::const_iterator>::pointer, const int*>::value, "span::const_iterator's pointer should be const int*"); static_assert(std::is_same::reverse_iterator, std::reverse_iterator::iterator>>::value, "span::reverse_iterator should equal std::reverse_iterator::iterator>"); static_assert(std::is_same::const_reverse_iterator, std::reverse_iterator::const_iterator>>::value, "span::const_reverse_iterator should equal " "std::reverse_iterator::const_iterator>"); // copyability assertions static_assert(std::is_trivially_copyable>::value, "span should be trivially copyable"); static_assert(std::is_trivially_copyable::iterator>::value, "span::iterator should be trivially copyable"); static_assert(std::is_trivially_copyable::const_iterator>::value, "span::const_iterator should be trivially copyable"); static_assert(std::is_trivially_copyable>::value, "span should be trivially copyable"); static_assert(std::is_trivially_copyable::iterator>::value, "span::iterator should be trivially copyable"); static_assert(std::is_trivially_copyable::const_iterator>::value, "span::const_iterator should be trivially copyable"); static_assert(std::is_trivially_copyable>::value, "span should be trivially copyable"); static_assert(std::is_trivially_copyable::iterator>::value, "span::iterator should be trivially copyable"); static_assert(std::is_trivially_copyable::const_iterator>::value, "span::const_iterator should be trivially copyable"); static_assert(std::is_trivially_copyable>::value, "span should be trivially copyable"); static_assert(std::is_trivially_copyable::iterator>::value, "span::iterator should be trivially copyable"); static_assert(std::is_trivially_copyable::const_iterator>::value, "span::const_iterator should be trivially copyable"); // nothrow constructible assertions static_assert(std::is_nothrow_constructible, int*, std::size_t>::value, "std::is_nothrow_constructible, int*, std::size_t>"); static_assert(std::is_nothrow_constructible, int*, std::uint16_t>::value, "std::is_nothrow_constructible, int*, std::uint16_t>"); static_assert(std::is_nothrow_constructible, int*, int*>::value, "std::is_nothrow_constructible, int*, int*>"); static_assert(std::is_nothrow_constructible, int (&)[3]>::value, "std::is_nothrow_constructible, int(&)[3]>"); static_assert(std::is_nothrow_constructible, const gsl::span&>::value, "std::is_nothrow_constructible, const gsl::span&>"); static_assert(std::is_nothrow_constructible, const gsl::span&>::value, "std::is_nothrow_constructible, const gsl::span&>"); static_assert(std::is_nothrow_constructible, const gsl::span&>::value, "std::is_nothrow_constructible, const gsl::span&>"); static_assert(std::is_nothrow_constructible, std::array&>::value, "std::is_nothrow_constructible, std::array&>"); static_assert(std::is_nothrow_constructible, int*, std::size_t>::value, "std::is_nothrow_constructible, int*, std::size_t>"); static_assert(std::is_nothrow_constructible, int*, std::uint16_t>::value, "std::is_nothrow_constructible, int*, std::uint16_t>"); static_assert(std::is_nothrow_constructible, int*, int*>::value, "std::is_nothrow_constructible, int*, int*>"); static_assert(std::is_nothrow_constructible, int (&)[3]>::value, "std::is_nothrow_constructible, int(&)[3]>"); static_assert(std::is_nothrow_constructible, const gsl::span&>::value, "std::is_nothrow_constructible, const gsl::span&>"); static_assert(std::is_nothrow_constructible, std::array&>::value, "std::is_nothrow_constructible, std::array&>"); static_assert(std::is_nothrow_constructible, int*, std::size_t>::value, "std::is_nothrow_constructible, int*, std::size_t>"); static_assert(std::is_nothrow_constructible, int*, int*>::value, "std::is_nothrow_constructible, int*, int*>"); static_assert(std::is_nothrow_constructible, int*, const int*>::value, "std::is_nothrow_constructible, int*, const int*>"); static_assert(std::is_nothrow_constructible, int (&)[3]>::value, "std::is_nothrow_constructible, int(&)[3]>"); static_assert(std::is_nothrow_constructible, const int*, int*>::value, "std::is_nothrow_constructible, const int*, int*>"); static_assert(std::is_nothrow_constructible, const int*, const int*>::value, "std::is_nothrow_constructible, const int*, const int*>"); static_assert(std::is_nothrow_constructible, const int*, std::size_t>::value, "std::is_nothrow_constructible, const int*, std::size_t>"); static_assert(std::is_nothrow_constructible, const int (&)[3]>::value, "std::is_nothrow_constructible, const int(&)[3]>"); static_assert(std::is_nothrow_constructible, const gsl::span&>::value, "std::is_nothrow_constructible, const gsl::span&>"); static_assert(std::is_nothrow_constructible, const gsl::span&>::value, "std::is_nothrow_constructible, const gsl::span&>"); static_assert( std::is_nothrow_constructible, const gsl::span&>::value, "std::is_nothrow_constructible, const gsl::span&>"); static_assert( std::is_nothrow_constructible, const gsl::span&>::value, "std::is_nothrow_constructible, const gsl::span&>"); static_assert( std::is_nothrow_constructible, const gsl::span&>::value, "std::is_nothrow_constructible, const gsl::span&>"); static_assert( std::is_nothrow_constructible, const gsl::span&>::value, "std::is_nothrow_constructible, const gsl::span&>"); static_assert(std::is_nothrow_constructible, std::array&>::value, "std::is_nothrow_constructible, std::array&>"); static_assert(std::is_nothrow_constructible, const std::array&>::value, "std::is_nothrow_constructible, const std::array&>"); static_assert( std::is_nothrow_constructible, const gsl::span&>::value, "std::is_nothrow_constructible, const gsl::span&>"); static_assert( std::is_nothrow_constructible, const gsl::span&>::value, "std::is_nothrow_constructible, const gsl::span&>"); static_assert(std::is_nothrow_constructible, Base (&)[3]>::value, "std::is_nothrow_constructible, Base(&)[3]>"); static_assert(std::is_nothrow_constructible, const gsl::span&>::value, "std::is_nothrow_constructible, const gsl::span&>"); static_assert(std::is_nothrow_constructible, const gsl::span&>::value, "std::is_nothrow_constructible, const gsl::span&>"); static_assert(std::is_nothrow_constructible, std::array&>::value, "std::is_nothrow_constructible, std::array&>"); static_assert(std::is_nothrow_constructible, Base (&)[3]>::value, "std::is_nothrow_constructible, Base(&)[3]>"); static_assert(std::is_nothrow_constructible, const gsl::span&>::value, "std::is_nothrow_constructible, const gsl::span&>"); static_assert(std::is_nothrow_constructible, std::array&>::value, "std::is_nothrow_constructible, std::array&>"); static_assert(std::is_nothrow_constructible, Base (&)[3]>::value, "std::is_nothrow_constructible, Base(&)[3]>"); static_assert(std::is_nothrow_constructible, const Base (&)[3]>::value, "std::is_nothrow_constructible, const Base(&)[3]>"); static_assert(std::is_nothrow_constructible, const gsl::span&>::value, "std::is_nothrow_constructible, const gsl::span&>"); static_assert( std::is_nothrow_constructible, const gsl::span&>::value, "std::is_nothrow_constructible, const gsl::span&>"); static_assert( std::is_nothrow_constructible, const gsl::span&>::value, "std::is_nothrow_constructible, const gsl::span&>"); static_assert( std::is_nothrow_constructible, const gsl::span&>::value, "std::is_nothrow_constructible, const gsl::span&>"); static_assert(std::is_nothrow_constructible, std::array&>::value, "std::is_nothrow_constructible, std::array&>"); static_assert( std::is_nothrow_constructible, const std::array&>::value, "std::is_nothrow_constructible, const std::array&>"); static_assert( std::is_nothrow_constructible, const gsl::span&>::value, "std::is_nothrow_constructible, const gsl::span&>"); static_assert( std::is_nothrow_constructible, const gsl::span&>::value, "std::is_nothrow_constructible, const gsl::span&>"); // non-constructible assertions static_assert(!std::is_constructible, const int*, int*>::value, "!std::is_constructible, const int*, int*>"); static_assert(!std::is_constructible, const int*, const int*>::value, "!std::is_constructible, const int*, const int*>"); static_assert(!std::is_constructible, const int*, double*>::value, "!std::is_constructible, const int*, double*>"); static_assert(!std::is_constructible, const int*, std::size_t>::value, "!std::is_constructible, const int*, std::size_t>"); static_assert(!std::is_constructible, const int (&)[3]>::value, "!std::is_constructible, const int(&)[3]>"); static_assert(!std::is_constructible, double*, int*>::value, "!std::is_constructible, double*, int*>"); static_assert(!std::is_constructible, double*, const int*>::value, "!std::is_constructible, double*, const int*>"); static_assert(!std::is_constructible, double*, double*>::value, "!std::is_constructible, double*, double*>"); static_assert(!std::is_constructible, double*, std::size_t>::value, "!std::is_constructible, double*, std::size_t>"); static_assert(!std::is_constructible, double (&)[3]>::value, "!std::is_constructible, double(&)[3]>"); static_assert(!std::is_constructible, int*, double*>::value, "!std::is_constructible, int*, double*>"); static_assert(!std::is_constructible, std::size_t, int*>::value, "!std::is_constructible, std::size_t, int*>"); static_assert(!std::is_constructible, std::size_t, std::size_t>::value, "!std::is_constructible, std::size_t, std::size_t>"); static_assert(!std::is_constructible, const gsl::span&>::value, "!std::is_constructible, const gsl::span&>"); static_assert(!std::is_constructible, const gsl::span&>::value, "!std::is_constructible, const gsl::span&>"); static_assert(!std::is_constructible, const gsl::span&>::value, "!std::is_constructible, const gsl::span&>"); static_assert(!std::is_constructible, const gsl::span&>::value, "!std::is_constructible, const gsl::span&>"); static_assert(!std::is_constructible, std::array&>::value, "!std::is_constructible, std::array&>"); static_assert(!std::is_constructible, const std::array&>::value, "!std::is_constructible, const std::array&>"); static_assert(!std::is_constructible, int*, double*>::value, "!std::is_constructible, int*, double*>"); static_assert(!std::is_constructible, int (&)[500]>::value, "!std::is_constructible, int(&)[500]>"); static_assert(!std::is_constructible, const int*, int*>::value, "!std::is_constructible, const int*, int*>"); static_assert(!std::is_constructible, const int*, const int*>::value, "!std::is_constructible, const int*, const int*>"); static_assert(!std::is_constructible, const int*, std::size_t>::value, "!std::is_constructible, const int*, std::size_t>"); static_assert(!std::is_constructible, const int*, double*>::value, "!std::is_constructible, const int*, double*>"); static_assert(!std::is_constructible, const int (&)[3]>::value, "!std::is_constructible, const int(&)[3]>"); static_assert(!std::is_constructible, double*, std::size_t>::value, "!std::is_constructible, double*, std::size_t>"); static_assert(!std::is_constructible, double*, int*>::value, "!std::is_constructible, double*, int*>"); static_assert(!std::is_constructible, double*, const int*>::value, "!std::is_constructible, double*, const int*>"); static_assert(!std::is_constructible, double*, double*>::value, "!std::is_constructible, double*, double*>"); static_assert(!std::is_constructible, double (&)[3]>::value, "!std::is_constructible, double(&)[3]>"); static_assert(!std::is_constructible, std::size_t, int*>::value, "!std::is_constructible, std::size_t, int*>"); static_assert(!std::is_constructible, std::size_t, std::size_t>::value, "!std::is_constructible, std::size_t, std::size_t>"); static_assert(!std::is_constructible, std::array&>::value, "!std::is_constructible, std::array&>"); static_assert(!std::is_constructible, std::array&>::value, "!std::is_constructible, std::array&>"); static_assert(!std::is_constructible, const std::array&>::value, "!std::is_constructible, const std::array&>"); static_assert(!std::is_constructible, const gsl::span&>::value, "!std::is_constructible, const gsl::span&>"); static_assert(!std::is_constructible, const gsl::span&>::value, "!std::is_constructible, const gsl::span&>"); static_assert(!std::is_constructible, const gsl::span&>::value, "!std::is_constructible, const gsl::span&>"); static_assert(!std::is_constructible, const gsl::span&>::value, "!std::is_constructible, const gsl::span&>"); static_assert(!std::is_constructible, const gsl::span&>::value, "!std::is_constructible, const gsl::span&>"); static_assert(!std::is_constructible, const gsl::span&>::value, "!std::is_constructible, const gsl::span&>"); static_assert(!std::is_constructible, double (&)[3]>::value, "!std::is_constructible, double(&)[3]>"); static_assert(!std::is_constructible, std::array&>::value, "!std::is_constructible, std::array&>"); static_assert(!std::is_constructible, const gsl::span&>::value, "!std::is_constructible, const gsl::span&>"); static_assert(!std::is_constructible, const gsl::span&>::value, "!std::is_constructible, const gsl::span&>"); static_assert(!std::is_constructible, const gsl::span&>::value, "!std::is_constructible, const gsl::span&>"); static_assert(!std::is_constructible, const gsl::span&>::value, "!std::is_constructible, const gsl::span&>"); static_assert( !std::is_constructible, const gsl::span&>::value, "!std::is_constructible, const gsl::span&>"); static_assert(!std::is_constructible, const gsl::span&>::value, "!std::is_constructible, const gsl::span&>"); static_assert(!std::is_constructible, Derived (&)[3]>::value, "!std::is_constructible, Derived(&)[3]>"); static_assert(!std::is_constructible, std::array&>::value, "!std::is_constructible, std::array&>"); static_assert(!std::is_constructible, std::vector&>::value, "!std::is_constructible, std::vector&>"); static_assert(!std::is_constructible, const gsl::span&>::value, "!std::is_constructible, const gsl::span&>"); static_assert(!std::is_constructible, const gsl::span&>::value, "!std::is_constructible, const gsl::span&>"); static_assert(!std::is_constructible, const gsl::span&>::value, "!std::is_constructible, const gsl::span&>"); static_assert(!std::is_constructible, Derived (&)[3]>::value, "!std::is_constructible, Derived(&)[3]>"); static_assert(!std::is_constructible, std::array&>::value, "!std::is_constructible, std::array&>"); static_assert(!std::is_constructible, Derived (&)[3]>::value, "!std::is_constructible, Derived(&)[3]>"); static_assert(!std::is_constructible, const Derived (&)[3]>::value, "!std::is_constructible, const Derived(&)[3]>"); static_assert(!std::is_constructible, std::array&>::value, "!std::is_constructible, std::array&>"); static_assert(!std::is_constructible, const std::array&>::value, "!std::is_constructible, const std::array&>"); static_assert(!std::is_constructible, const gsl::span&>::value, "!std::is_constructible, const gsl::span&>"); static_assert(!std::is_constructible, const gsl::span&>::value, "!std::is_constructible, const gsl::span&>"); static_assert(!std::is_constructible, const gsl::span&>::value, "!std::is_constructible, const gsl::span&>"); static_assert( !std::is_constructible, const gsl::span&>::value, "!std::is_constructible, const gsl::span&>"); static_assert(!std::is_constructible, const gsl::span&>::value, "!std::is_constructible, const gsl::span&>"); static_assert( !std::is_constructible, const gsl::span&>::value, "!std::is_constructible, const gsl::span&>"); static_assert(!std::is_constructible, std::array&>::value, "!std::is_constructible, std::array&>"); static_assert(!std::is_constructible, const std::array&>::value, "!std::is_constructible, const std::array&>"); // no throw copy constructor static_assert(std::is_nothrow_copy_constructible>::value, "std::is_nothrow_copy_constructible>"); static_assert(std::is_nothrow_copy_constructible>::value, "std::is_nothrow_copy_constructible>"); static_assert(std::is_nothrow_copy_constructible>::value, "std::is_nothrow_copy_constructible>"); static_assert(std::is_nothrow_copy_constructible>::value, "std::is_nothrow_copy_constructible>"); // no throw copy assignment static_assert(std::is_nothrow_copy_assignable>::value, "std::is_nothrow_copy_assignable>"); static_assert(std::is_nothrow_copy_assignable>::value, "std::is_nothrow_copy_assignable>"); static_assert(std::is_nothrow_copy_assignable>::value, "std::is_nothrow_copy_assignable>"); static_assert(std::is_nothrow_copy_assignable>::value, "std::is_nothrow_copy_assignable>"); // no throw destruction static_assert(std::is_nothrow_destructible>::value, "std::is_nothrow_destructible>"); static_assert(std::is_nothrow_destructible>::value, "std::is_nothrow_destructible>"); static_assert(std::is_nothrow_destructible>::value, "std::is_nothrow_destructible>"); // conversions static_assert(std::is_convertible>::value, "std::is_convertible>"); static_assert(std::is_convertible>::value, "std::is_convertible>"); static_assert(std::is_convertible>::value, "std::is_convertible>"); static_assert(std::is_convertible>::value, "std::is_convertible>"); static_assert(std::is_convertible&, gsl::span>::value, "std::is_convertible&, gsl::span>"); static_assert(std::is_convertible&, gsl::span>::value, "std::is_convertible&, gsl::span>"); static_assert(std::is_convertible&, gsl::span>::value, "std::is_convertible&, gsl::span>"); static_assert(std::is_convertible&, gsl::span>::value, "std::is_convertible&, gsl::span>"); static_assert(std::is_convertible&, gsl::span>::value, "std::is_convertible&, gsl::span>"); static_assert(std::is_convertible&, gsl::span>::value, "std::is_convertible&, gsl::span>"); static_assert(std::is_convertible&, gsl::span>::value, "std::is_convertible&, gsl::span>"); static_assert(std::is_convertible&, gsl::span>::value, "std::is_convertible&, gsl::span>"); static_assert(std::is_convertible&, gsl::span>::value, "std::is_convertible&, gsl::span>"); static_assert(std::is_convertible&, gsl::span>::value, "std::is_convertible&, gsl::span>"); static_assert(std::is_convertible&, gsl::span>::value, "std::is_convertible&, gsl::span>"); static_assert(std::is_convertible&, gsl::span>::value, "std::is_convertible&, gsl::span>"); static_assert(std::is_convertible&, gsl::span>::value, "std::is_convertible&, gsl::span>"); static_assert(std::is_convertible&, gsl::span>::value, "std::is_convertible&, gsl::span>"); static_assert(std::is_convertible&, gsl::span>::value, "std::is_convertible&, gsl::span>"); static_assert(std::is_convertible&, gsl::span>::value, "std::is_convertible&, gsl::span>"); #if __cplusplus >= 201703l template static constexpr bool AsWritableBytesCompilesFor = false; template static constexpr bool AsWritableBytesCompilesFor()))>> = true; static_assert(AsWritableBytesCompilesFor>, "AsWritableBytesCompilesFor>"); static_assert(AsWritableBytesCompilesFor>, "AsWritableBytesCompilesFor>"); static_assert(!AsWritableBytesCompilesFor>, "!AsWritableBytesCompilesFor>"); static_assert(!AsWritableBytesCompilesFor>, "!AsWritableBytesCompilesFor>"); #endif // __cplusplus >= 201703l