diff --git a/gsl/span b/gsl/span index aec826a..0651329 100644 --- a/gsl/span +++ b/gsl/span @@ -670,6 +670,19 @@ span make_span(Ptr& cont) { return span(cont); } +template ::value>> +span +as_bytes(const T& e) noexcept +{ + return{ reinterpret_cast(&e),sizeof(T) }; +} + +template ::value>> +span +as_writeable_bytes(T& e) noexcept +{ + return{ reinterpret_cast(&e),sizeof(T) }; +} // Specialization of gsl::at for span template diff --git a/tests/span_tests.cpp b/tests/span_tests.cpp index 9669464..d622eb7 100644 --- a/tests/span_tests.cpp +++ b/tests/span_tests.cpp @@ -1444,6 +1444,47 @@ SUITE(span_tests) } } + struct MyTriviallyCopyableType { + MyTriviallyCopyableType(int i) :a(i), b(static_cast(i)), c(i) {} + int a; + char b; + double c; + friend bool operator==(MyTriviallyCopyableType& l, MyTriviallyCopyableType& r) { return l.a == r.a && l.b == r.b && l.c == r.c; } + }; + + TEST(pod_as_bytes) + { + { + double src{ 10.5 }; + double dst{}; + auto src_b = as_bytes(src); + auto dst_b = as_writeable_bytes(dst); + std::copy(src_b.begin(), src_b.end(), dst_b.begin()); + CHECK(std::equal(src_b.begin(), src_b.end(), dst_b.begin())); + CHECK(src == dst); + } + { + std::array src{ 1,2,3,4,5,6,7,8,9,10 }; + std::array dst{}; + auto src_b = as_bytes(src); + auto dst_b = as_writeable_bytes(dst); + std::copy(src_b.begin(), src_b.end(), dst_b.begin()); + CHECK(std::equal(src_b.begin(), src_b.end(), dst_b.begin())); + CHECK(src == dst); + } +#ifdef CONFIRM_COMPILATION_ERRORS + { + MyTC_t src{ 5 }; + MyTC_t dst{ 1 }; + auto src_b = as_bytes(src); + auto dst_b = as_writeable_bytes(dst); + std::copy(src_b.begin(), src_b.end(), dst_b.begin()); + CHECK(std::equal(src_b.begin(), src_b.end(), dst_b.begin())); + CHECK(src == dst); + } +#endif + } + TEST(fixed_size_conversions) { int arr[] = {1, 2, 3, 4};