From 2b51b8767a31edbcfb6ee5642552c45f65db1c27 Mon Sep 17 00:00:00 2001 From: Rian Quinn Date: Thu, 3 Nov 2016 19:55:41 -0600 Subject: [PATCH] Add span construction from unique_ptr and shared_ptr This patch adds support for std::unique_ptr and std::shared_ptr to the gsl::span class instead of having to manually grab the pointer via get(). For reference, this is part of the following issue: https://github.com/Microsoft/GSL/issues/402 --- gsl/span | 7 +++++ tests/span_tests.cpp | 66 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/gsl/span b/gsl/span index 3a3fb52..0925344 100644 --- a/gsl/span +++ b/gsl/span @@ -29,6 +29,7 @@ #include #include #include +#include #ifdef _MSC_VER @@ -386,6 +387,12 @@ public: { } + template> + constexpr span(const std::unique_ptr& ptr, index_type count) : storage_(ptr.get(), count) {} + + constexpr span(const std::unique_ptr& ptr) : storage_(ptr.get(), ptr.get() ? 1 : 0) {} + constexpr span(const std::shared_ptr& ptr) : storage_(ptr.get(), ptr.get() ? 1 : 0) {} + // NB: the SFINAE here uses .data() as a incomplete/imperfect proxy for the requirement // on Container to be a contiguous sequence container. template (4); + + { + span s{ptr}; + CHECK(s.length() == 1 && s.data() == ptr.get()); + CHECK(s[0] == 4); + } + } + + { + auto ptr = std::unique_ptr{nullptr}; + + { + span s{ptr}; + CHECK(s.length() == 0 && s.data() == nullptr); + } + } + + { + auto arr = std::make_unique(4); + + for (auto i = 0; i < 4; i++) + arr[i] = i + 1; + + { + span s{arr, 4}; + CHECK(s.length() == 4 && s.data() == arr.get()); + CHECK(s[0] == 1 && s[1] == 2); + } + } + + { + auto ptr = std::unique_ptr{nullptr}; + + { + span s{ptr, 0}; + CHECK(s.length() == 0 && s.data() == nullptr); + } + } + } + + TEST(from_shared_pointer_construction) + { + { + auto ptr = std::make_shared(4); + + { + span s{ptr}; + CHECK(s.length() == 1 && s.data() == ptr.get()); + CHECK(s[0] == 4); + } + } + + { + auto ptr = std::shared_ptr{nullptr}; + + { + span s{ptr}; + CHECK(s.length() == 0 && s.data() == nullptr); + } + } + } + TEST(from_container_constructor) { std::vector v = {1, 2, 3};