diff --git a/include/span.h b/include/span.h index eab2659..3c5b53d 100644 --- a/include/span.h +++ b/include/span.h @@ -92,6 +92,53 @@ template struct is_span : is_span_oracle> { }; + +template +struct is_allowed_pointer_conversion + : std::integral_constant::value && + std::is_pointer::value && + std::is_convertible::value + > +{ +}; + +template +struct is_allowed_integral_conversion + : std::integral_constant::value && + std::is_integral::value && + sizeof(From) == sizeof(To) && + alignof(From) == alignof(To) && + std::is_convertible::value + > +{ +}; + +template +struct is_allowed_element_type_conversion + : std::integral_constant>::value || + is_allowed_pointer_conversion::value || + is_allowed_integral_conversion::value + > +{ +}; + +template +struct is_allowed_element_type_conversion + : std::integral_constant::value> +{ +}; + +template +struct is_allowed_element_type_conversion + : std::integral_constant +{ +}; + + + } // namespace details @@ -163,13 +210,29 @@ public: > span(const Container&&) = delete; -#if 0 // TODO constexpr span(const span& other) noexcept = default; constexpr span(span&& other) noexcept = default; - template - constexpr span(const span& other); - template - constexpr span(span&& other); + + template ::value && + details::is_allowed_element_type_conversion::value + > + > + constexpr span(const span& other) + : storage_(reinterpret_cast(other.data()), other.length()) + {} + + template ::value && + details::is_allowed_element_type_conversion::value + > + > + constexpr span(span&& other) + : storage_(reinterpret_cast(other.data()), other.length()) + { + } + +#if 0 // TODO ~span() noexcept = default; constexpr span& operator=(const span& other) noexcept = default; constexpr span& operator=(span&& other) noexcept = default; diff --git a/tests/span_tests.cpp b/tests/span_tests.cpp index e68493c..0b65507 100644 --- a/tests/span_tests.cpp +++ b/tests/span_tests.cpp @@ -512,34 +512,44 @@ SUITE(span_tests) #endif } } -#if 0 + TEST(from_convertible_span_constructor) { + { + span avd; + span avcd = avd; + (void)avcd; + } + + { #ifdef CONFIRM_COMPILATION_ERRORS - span av1(nullptr, b1); - - auto f = [&]() { span av1(nullptr); }; - CHECK_THROW(f(), fail_fast); + span avd; + span avb = avd; + (void) avb; #endif + } + { + span s; + span s2 = s; + (void)s2; + } + + { + span s; + span s2 = s; + (void)s2; + } + + { #ifdef CONFIRM_COMPILATION_ERRORS - static_bounds b12(b11); - b12 = b11; - b11 = b12; - - span av1 = nullptr; - span av2(av1); - span av2(av1); + span s; + span s2 = s; + (void)s2; #endif - - span avd; -#ifdef CONFIRM_COMPILATION_ERRORS - span avb = avd; -#endif - span avcd = avd; - (void) avcd; + } } - +#if 0 TEST(copy_move_and_assignment) { span s1;