span_tests.cpp
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()