mirror of
https://github.com/microsoft/GSL.git
synced 2024-11-03 17:56:43 -05:00
Added span to object rep conversions.
This commit is contained in:
parent
d63c9803da
commit
ba8ebef509
33
include/byte.h
Normal file
33
include/byte.h
Normal file
@ -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
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include "gsl_assert.h"
|
||||
#include "gsl_util.h"
|
||||
#include "byte.h"
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cassert>
|
||||
@ -1053,9 +1054,6 @@ template <typename Span>
|
||||
class contiguous_span_iterator;
|
||||
template <typename Span>
|
||||
class general_span_iterator;
|
||||
enum class byte : std::uint8_t
|
||||
{
|
||||
};
|
||||
|
||||
template <std::ptrdiff_t DimSize = dynamic_range>
|
||||
struct dim
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include "gsl_assert.h"
|
||||
#include "gsl_util.h"
|
||||
#include "byte.h"
|
||||
#include <array>
|
||||
#include <limits>
|
||||
#include <iterator>
|
||||
@ -126,13 +127,13 @@ struct is_allowed_element_type_conversion
|
||||
};
|
||||
|
||||
template <class From>
|
||||
struct is_allowed_element_type_conversion<From, char>
|
||||
struct is_allowed_element_type_conversion<From, byte>
|
||||
: std::integral_constant<bool, !std::is_const<From>::value>
|
||||
{
|
||||
};
|
||||
|
||||
template <class From>
|
||||
struct is_allowed_element_type_conversion<From, const char>
|
||||
struct is_allowed_element_type_conversion<From, const byte>
|
||||
: std::integral_constant<bool, true>
|
||||
{
|
||||
};
|
||||
@ -507,14 +508,33 @@ constexpr bool operator>=(const span<ElementType, Extent>& l, const span<Element
|
||||
{ return !(l < r); }
|
||||
|
||||
|
||||
#if 0 // TODO
|
||||
namespace details
|
||||
{
|
||||
// if we only supported compilers with good constexpr support then
|
||||
// this pair of classes could collapse down to a constexpr function
|
||||
|
||||
// we should use a narrow_cast<> to go to size_t, but older compilers may not see it as constexpr
|
||||
// and so will fail compilation of the template
|
||||
template <class ElementType, ptrdiff_t Extent>
|
||||
struct calculate_byte_size :
|
||||
std::integral_constant<std::ptrdiff_t, static_cast<ptrdiff_t>(sizeof(ElementType) * static_cast<size_t>(Extent))>
|
||||
{};
|
||||
|
||||
template <class ElementType>
|
||||
struct calculate_byte_size<ElementType, dynamic_extent> :
|
||||
std::integral_constant<std::ptrdiff_t, dynamic_extent>
|
||||
{};
|
||||
}
|
||||
|
||||
|
||||
// [span.objectrep], views of object representation
|
||||
template <class ElementType, ptrdiff_t Extent>
|
||||
constexpr span<const char, ((Extent == dynamic_extent) ? dynamic_extent : (sizeof(ElementType) * Extent))> as_bytes(span<ElementType, Extent> s) noexcept;
|
||||
constexpr span<const byte, details::calculate_byte_size<ElementType, Extent>::value> as_bytes(span<ElementType, Extent> s) noexcept
|
||||
{ return {reinterpret_cast<const byte*>(s.data()), s.size_bytes()}; }
|
||||
|
||||
template <class ElementType, ptrdiff_t Extent>
|
||||
constexpr span<char, ((Extent == dynamic_extent) ? dynamic_extent : (sizeof(ElementType) * Extent))> as_writeable_bytes(span<ElementType, Extent>) noexcept;
|
||||
#endif
|
||||
template <class ElementType, ptrdiff_t Extent, class = std::enable_if_t<!std::is_const<ElementType>::value>>
|
||||
constexpr span<byte, details::calculate_byte_size<ElementType, Extent>::value> as_writeable_bytes(span<ElementType, Extent> s) noexcept
|
||||
{ return {reinterpret_cast<byte*>(s.data()), s.size_bytes()}; }
|
||||
|
||||
} // namespace gsl
|
||||
|
||||
|
@ -921,6 +921,69 @@ SUITE(span_tests)
|
||||
}
|
||||
}
|
||||
|
||||
TEST(as_bytes)
|
||||
{
|
||||
int a[] = {1, 2, 3, 4};
|
||||
|
||||
{
|
||||
span<const int> s = a;
|
||||
CHECK(s.length() == 4);
|
||||
span<const byte> bs = as_bytes(s);
|
||||
CHECK(static_cast<const void*>(bs.data()) == static_cast<const void*>(s.data()));
|
||||
CHECK(bs.length() == s.length_bytes());
|
||||
}
|
||||
|
||||
{
|
||||
span<int> s;
|
||||
auto bs = as_bytes(s);
|
||||
CHECK(bs.length() == s.length());
|
||||
CHECK(bs.length() == 0);
|
||||
CHECK(bs.size_bytes() == 0);
|
||||
CHECK(static_cast<const void*>(bs.data()) == static_cast<const void*>(s.data()));
|
||||
CHECK(bs.data() == nullptr);
|
||||
}
|
||||
|
||||
{
|
||||
span<int> s = a;
|
||||
auto bs = as_bytes(s);
|
||||
CHECK(static_cast<const void*>(bs.data()) == static_cast<const void*>(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<const int> s = a;
|
||||
CHECK(s.length() == 4);
|
||||
span<const byte> bs = as_writeable_bytes(s);
|
||||
CHECK(static_cast<void*>(bs.data()) == static_cast<void*>(s.data()));
|
||||
CHECK(bs.length() == s.length_bytes());
|
||||
#endif
|
||||
}
|
||||
|
||||
{
|
||||
span<int> s;
|
||||
auto bs = as_writeable_bytes(s);
|
||||
CHECK(bs.length() == s.length());
|
||||
CHECK(bs.length() == 0);
|
||||
CHECK(bs.size_bytes() == 0);
|
||||
CHECK(static_cast<void*>(bs.data()) == static_cast<void*>(s.data()));
|
||||
CHECK(bs.data() == nullptr);
|
||||
}
|
||||
|
||||
{
|
||||
span<int> s = a;
|
||||
auto bs = as_writeable_bytes(s);
|
||||
CHECK(static_cast<void*>(bs.data()) == static_cast<void*>(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<const int, dynamic_range> av = a;
|
||||
auto wav = av.as_writeable_bytes();
|
||||
#endif
|
||||
}
|
||||
|
||||
{
|
||||
span<int, dynamic_range> av;
|
||||
auto wav = as_writeable_bytes(av);
|
||||
CHECK(wav.length() == av.length());
|
||||
CHECK(wav.length() == 0);
|
||||
CHECK(wav.size_bytes() == 0);
|
||||
}
|
||||
|
||||
{
|
||||
span<int, dynamic_range> av = a;
|
||||
auto wav = as_writeable_bytes(av);
|
||||
CHECK(wav.data() == (byte*) &a[0]);
|
||||
CHECK(wav.length() == sizeof(a));
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user