From edc0d935c041aa5c115ff483806d901a6b1ed472 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Sat, 28 Jan 2023 12:23:58 -0500 Subject: [PATCH] Implement make_span --- doc/core.qbk | 1 + doc/make_span.qbk | 81 +++++++++++++++++++++++++ include/boost/core/make_span.hpp | 59 ++++++++++++++++++ test/Jamfile.v2 | 1 + test/make_span_test.cpp | 100 +++++++++++++++++++++++++++++++ 5 files changed, 242 insertions(+) create mode 100644 doc/make_span.qbk create mode 100644 include/boost/core/make_span.hpp create mode 100644 test/make_span_test.cpp diff --git a/doc/core.qbk b/doc/core.qbk index 3cddc75..a184a98 100644 --- a/doc/core.qbk +++ b/doc/core.qbk @@ -58,6 +58,7 @@ criteria for inclusion is that the utility component be: [include is_same.qbk] [include launder.qbk] [include lightweight_test.qbk] +[include make_span.qbk] [include max_align.qbk] [include memory_resource.qbk] [include no_exceptions_support.qbk] diff --git a/doc/make_span.qbk b/doc/make_span.qbk new file mode 100644 index 0000000..b6f6652 --- /dev/null +++ b/doc/make_span.qbk @@ -0,0 +1,81 @@ +[/ +Copyright 2023 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +] + +[section:make_span make_span] + +[simplesect Authors] + +* Glen Fernandes + +[endsimplesect] + +[section Overview] + +The header provides function templates `make_span` +to conveniently create `span` objects. They are useful before C++17 where Class +Template Argument Deduction (CTAD) is not available. + +[endsect] + +[section Reference] + +``` +namespace boost { + +template +constexpr span +make_span(I* d, std::size_t n) noexcept; + +template +constexpr span +make_span(I* b, I* e) noexcept; + +template +constexpr span +make_span(T(&a)[N]) noexcept; + +template +constexpr span +make_span(std::array& a) noexcept; + +template +constexpr span +make_span(const std::array& a) noexcept; + +template +span().data())> > +make_span(R&& r); + +} /* boost */ +``` + +[section Functions] + +[variablelist +[[`template span make_span(I* f, std::size_t c);`] +[Returns `span(f, c)`.]] +[[`template span make_span(I* f, I* l);`] +[Returns `span(f, l)`.]] +[[`template span make_span(T(&a)[N]);`] +[Returns `span(a)`.]] +[[`template span +make_span(std::array& a);`] +[Returns `span(a)`.]] +[[`template span +make_span(const std::array& a);`] +[Returns `span(a)`.]] +[[`template +span().data())> > +make_span(R&& r);`] +[Returns `span<>(std::forward(r))`.]]] + +[endsect] + +[endsect] + +[endsect] diff --git a/include/boost/core/make_span.hpp b/include/boost/core/make_span.hpp new file mode 100644 index 0000000..5f5df56 --- /dev/null +++ b/include/boost/core/make_span.hpp @@ -0,0 +1,59 @@ +/* +Copyright 2023 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#ifndef BOOST_CORE_MAKE_SPAN_HPP +#define BOOST_CORE_MAKE_SPAN_HPP + +#include + +namespace boost { + +template +inline constexpr span +make_span(I* f, std::size_t c) noexcept +{ + return span(f, c); +} + +template +inline constexpr span +make_span(I* f, I* l) noexcept +{ + return span(f, l); +} + +template +inline constexpr span +make_span(T(&a)[N]) noexcept +{ + return span(a); +} + +template +inline constexpr span +make_span(std::array& a) noexcept +{ + return span(a); +} + +template +inline constexpr span +make_span(const std::array& a) noexcept +{ + return span(a); +} + +template +inline span::type> +make_span(R&& r) +{ + return span::type>(std::forward(r)); +} + +} /* boost */ + +#endif diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index eeae530..65e17ae 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -343,6 +343,7 @@ run span_deduction_guide_test.cpp ; run as_bytes_test.cpp ; run as_writable_bytes_test.cpp ; compile span_boost_begin_test.cpp ; +run make_span_test.cpp ; run splitmix64_test.cpp : : : $(pedantic-errors) ; diff --git a/test/make_span_test.cpp b/test/make_span_test.cpp new file mode 100644 index 0000000..c840046 --- /dev/null +++ b/test/make_span_test.cpp @@ -0,0 +1,100 @@ +/* +Copyright 2023 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include +#if !defined(BOOST_NO_CXX11_CONSTEXPR) && !defined(BOOST_NO_CXX11_DECLTYPE) +#include +#include + +template +class range { +public: + T* data() { + return &v_[0]; + } + + std::size_t size() const { + return 4; + } + +private: + T v_[4]; +}; + +void test_data_size() +{ + int a[4]; + boost::span s = boost::make_span(&a[0], 4); + BOOST_TEST_EQ(s.data(), &a[0]); + BOOST_TEST_EQ(s.size(), 4); +} + +void test_first_last() +{ + int a[4]; + boost::span s = boost::make_span(&a[0], &a[4]); + BOOST_TEST_EQ(s.data(), &a[0]); + BOOST_TEST_EQ(s.size(), 4); +} + +void test_array() +{ + int a[4]; + boost::span s = boost::make_span(a); + BOOST_TEST_EQ(s.data(), &a[0]); + BOOST_TEST_EQ(s.size(), 4); +} + +void test_std_array() +{ + std::array a; + boost::span s = boost::make_span(a); + BOOST_TEST_EQ(s.data(), a.data()); + BOOST_TEST_EQ(s.size(), a.size()); +} + +void test_const_std_array() +{ + const std::array a = std::array(); + boost::span s = boost::make_span(a); + BOOST_TEST_EQ(s.data(), a.data()); + BOOST_TEST_EQ(s.size(), a.size()); +} + +void test_range() +{ + range c; + boost::span s = boost::make_span(c); + BOOST_TEST_EQ(s.data(), c.data()); + BOOST_TEST_EQ(s.size(), c.size()); +} + +void test_initializer_list() +{ + std::initializer_list l{1, 2}; + boost::span s = boost::make_span(l); + BOOST_TEST_EQ(s.data(), l.begin()); + BOOST_TEST_EQ(s.size(), l.size()); +} + +int main() +{ + test_data_size(); + test_first_last(); + test_array(); + test_std_array(); + test_const_std_array(); + test_range(); + test_initializer_list(); + return boost::report_errors(); +} +#else +int main() +{ + return 0; +} +#endif