span_tests.cpp raw
1 // Copyright (c) 2023-present The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5 #include <span.h>
6
7 #include <boost/test/unit_test.hpp>
8 #include <array>
9 #include <set>
10 #include <vector>
11
12 namespace spannable {
13 struct Ignore
14 {
15 template<typename T> Ignore(T&&) {}
16 };
17 template<typename T>
18 bool Spannable(T&& value, decltype(std::span{value})* enable = nullptr)
19 {
20 return true;
21 }
22 bool Spannable(Ignore)
23 {
24 return false;
25 }
26
27 struct SpannableYes
28 {
29 int* data();
30 int* begin();
31 int* end();
32 size_t size();
33 };
34 struct SpannableNo
35 {
36 void data();
37 size_t size();
38 };
39 } // namespace spannable
40
41 using namespace spannable;
42
43 BOOST_AUTO_TEST_SUITE(span_tests)
44
45 // Make sure template std::span template deduction guides accurately enable calls to
46 // std::span constructor overloads that work, and disable calls to constructor overloads that
47 // don't work. This makes it possible to use the std::span constructor in a SFINAE
48 // contexts like in the Spannable function above to detect whether types are or
49 // aren't compatible with std::span at compile time.
50 BOOST_AUTO_TEST_CASE(span_constructor_sfinae)
51 {
52 BOOST_CHECK(Spannable(std::vector<int>{}));
53 BOOST_CHECK(!Spannable(std::set<int>{}));
54 BOOST_CHECK(!Spannable(std::vector<bool>{}));
55 BOOST_CHECK(Spannable(std::array<int, 3>{}));
56 BOOST_CHECK(Spannable(std::span<int>{}));
57 BOOST_CHECK(Spannable("char array"));
58 BOOST_CHECK(Spannable(SpannableYes{}));
59 BOOST_CHECK(!Spannable(SpannableNo{}));
60 }
61
62 BOOST_AUTO_TEST_SUITE_END()
63