mirror of
https://github.com/matrix-construct/construct
synced 2024-11-25 16:22:35 +01:00
76 lines
1.8 KiB
C++
76 lines
1.8 KiB
C++
// Matrix Construct
|
|
//
|
|
// Copyright (C) Matrix Construct Developers, Authors & Contributors
|
|
// Copyright (C) 2016-2018 Jason Volk <jason@zemos.net>
|
|
//
|
|
// Permission to use, copy, modify, and/or distribute this software for any
|
|
// purpose with or without fee is hereby granted, provided that the above
|
|
// copyright notice and this permission notice is present in all copies. The
|
|
// full license for this software is available in the LICENSE file.
|
|
|
|
#pragma once
|
|
#define HAVE_IRCD_BYTE_VIEW_H
|
|
|
|
namespace ircd
|
|
{
|
|
template<class T = string_view,
|
|
bool safety = true>
|
|
struct byte_view;
|
|
|
|
template<> struct byte_view<string_view>;
|
|
}
|
|
|
|
/// bytes -> string_view. A byte_view<string_view> is raw data of byte_view<T>.
|
|
///
|
|
/// This is an important specialization to take note of. When you see
|
|
/// byte_view<string_view> know that another type's bytes are being represented
|
|
/// by the string_view if that type is not string_view family itself.
|
|
template<>
|
|
struct ircd::byte_view<ircd::string_view>
|
|
:string_view
|
|
{
|
|
template<class T,
|
|
typename std::enable_if<!std::is_base_of<std::string_view, T>::value, int *>::type = nullptr>
|
|
byte_view(const T &t)
|
|
:string_view{reinterpret_cast<const char *>(&t), sizeof(T)}
|
|
{}
|
|
|
|
/// string_view -> string_view (completeness)
|
|
byte_view(const string_view &t = {})
|
|
:string_view{t}
|
|
{}
|
|
};
|
|
|
|
/// string_view -> bytes
|
|
template<class T,
|
|
bool safety>
|
|
struct ircd::byte_view
|
|
{
|
|
string_view s;
|
|
|
|
operator const T &() const;
|
|
|
|
byte_view(const string_view &s = {})
|
|
:s{s}
|
|
{}
|
|
|
|
// bytes -> bytes (completeness)
|
|
byte_view(const T &t)
|
|
:s{byte_view<string_view>{t}}
|
|
{}
|
|
};
|
|
|
|
template<class T,
|
|
bool safety>
|
|
inline ircd::byte_view<T, safety>::operator
|
|
const T &()
|
|
const
|
|
{
|
|
assert(sizeof(T) <= size(s));
|
|
|
|
if constexpr(safety)
|
|
if(unlikely(sizeof(T) > s.size()))
|
|
throw std::bad_cast();
|
|
|
|
return *reinterpret_cast<const T *>(s.data());
|
|
}
|