diff --git a/include/byte.h b/include/byte.h new file mode 100644 index 0000000..c6449aa --- /dev/null +++ b/include/byte.h @@ -0,0 +1,33 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2015 Microsoft Corporation. All rights reserved. +// +// This code is licensed under the MIT License (MIT). +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +/////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#ifndef GSL_BYTE_H +#define GSL_BYTE_H + +namespace gsl +{ + // This is a simple definition for now that allows + // use of byte within span<> to be standards-compliant + // + // Ultimately a small language change would allow a more + // robust definition (see WG21 proposal P0257 for details). + using byte = unsigned char; + +} // namespace gsl + +#endif // GSL_BYTE_H \ No newline at end of file diff --git a/include/multi_span.h b/include/multi_span.h index 523f324..3d00c6e 100644 --- a/include/multi_span.h +++ b/include/multi_span.h @@ -21,6 +21,7 @@ #include "gsl_assert.h" #include "gsl_util.h" +#include "byte.h" #include #include #include @@ -1053,9 +1054,6 @@ template class contiguous_span_iterator; template class general_span_iterator; -enum class byte : std::uint8_t -{ -}; template struct dim diff --git a/include/span.h b/include/span.h index 2760121..7152c2d 100644 --- a/include/span.h +++ b/include/span.h @@ -21,6 +21,7 @@ #include "gsl_assert.h" #include "gsl_util.h" +#include "byte.h" #include #include #include @@ -126,13 +127,13 @@ struct is_allowed_element_type_conversion }; template -struct is_allowed_element_type_conversion +struct is_allowed_element_type_conversion : std::integral_constant::value> { }; template -struct is_allowed_element_type_conversion +struct is_allowed_element_type_conversion : std::integral_constant { }; @@ -507,14 +508,33 @@ constexpr bool operator>=(const span& l, const span to go to size_t, but older compilers may not see it as constexpr + // and so will fail compilation of the template + template + struct calculate_byte_size : + std::integral_constant(sizeof(ElementType) * static_cast(Extent))> + {}; + + template + struct calculate_byte_size : + std::integral_constant + {}; +} + + // [span.objectrep], views of object representation template -constexpr span as_bytes(span s) noexcept; +constexpr span::value> as_bytes(span s) noexcept +{ return {reinterpret_cast(s.data()), s.size_bytes()}; } -template -constexpr span as_writeable_bytes(span) noexcept; -#endif +template ::value>> +constexpr span::value> as_writeable_bytes(span s) noexcept +{ return {reinterpret_cast(s.data()), s.size_bytes()}; } } // namespace gsl diff --git a/tests/span_tests.cpp b/tests/span_tests.cpp index 694d9a2..ddae404 100644 --- a/tests/span_tests.cpp +++ b/tests/span_tests.cpp @@ -921,6 +921,69 @@ SUITE(span_tests) } } + TEST(as_bytes) + { + int a[] = {1, 2, 3, 4}; + + { + span s = a; + CHECK(s.length() == 4); + span bs = as_bytes(s); + CHECK(static_cast(bs.data()) == static_cast(s.data())); + CHECK(bs.length() == s.length_bytes()); + } + + { + span s; + auto bs = as_bytes(s); + CHECK(bs.length() == s.length()); + CHECK(bs.length() == 0); + CHECK(bs.size_bytes() == 0); + CHECK(static_cast(bs.data()) == static_cast(s.data())); + CHECK(bs.data() == nullptr); + } + + { + span s = a; + auto bs = as_bytes(s); + CHECK(static_cast(bs.data()) == static_cast(s.data())); + CHECK(bs.length() == s.length_bytes()); + } + } + + TEST(as_writeable_bytes) + { + int a[] = {1, 2, 3, 4}; + + { +#ifdef CONFIRM_COMPILATION_ERRORS + // you should not be able to get writeable bytes for const objects + span s = a; + CHECK(s.length() == 4); + span bs = as_writeable_bytes(s); + CHECK(static_cast(bs.data()) == static_cast(s.data())); + CHECK(bs.length() == s.length_bytes()); +#endif + } + + { + span s; + auto bs = as_writeable_bytes(s); + CHECK(bs.length() == s.length()); + CHECK(bs.length() == 0); + CHECK(bs.size_bytes() == 0); + CHECK(static_cast(bs.data()) == static_cast(s.data())); + CHECK(bs.data() == nullptr); + } + + { + span s = a; + auto bs = as_writeable_bytes(s); + CHECK(static_cast(bs.data()) == static_cast(s.data())); + CHECK(bs.length() == s.length_bytes()); + } + } + #if 0 TEST(fixed_size_conversions) { @@ -1018,34 +1081,6 @@ SUITE(span_tests) CHECK_THROW(f(), fail_fast); } - TEST(as_writeable_bytes) - { - int a[] = {1, 2, 3, 4}; - - { -#ifdef CONFIRM_COMPILATION_ERRORS - // you should not be able to get writeable bytes for const objects - span av = a; - auto wav = av.as_writeable_bytes(); -#endif - } - - { - span av; - auto wav = as_writeable_bytes(av); - CHECK(wav.length() == av.length()); - CHECK(wav.length() == 0); - CHECK(wav.size_bytes() == 0); - } - - { - span av = a; - auto wav = as_writeable_bytes(av); - CHECK(wav.data() == (byte*) &a[0]); - CHECK(wav.length() == sizeof(a)); - } - } - #endif }