#ifndef _C4_BLOB_HPP_ #define _C4_BLOB_HPP_ #include "c4/types.hpp" #include "c4/error.hpp" /** @file blob.hpp Mutable and immutable binary data blobs. */ namespace c4 { template struct blob_; namespace detail { template struct is_blob_type : std::integral_constant {}; template struct is_blob_type> : std::integral_constant {}; template struct is_blob_value_type : std::integral_constant::value || std::is_trivially_copyable::value)> {}; } // namespace template struct blob_ { static_assert(std::is_same::value || std::is_same::value, "must be either byte or cbyte"); static_assert(sizeof(T) == 1u, "must be either byte or cbyte"); public: T * buf; size_t len; public: C4_ALWAYS_INLINE blob_() noexcept = default; C4_ALWAYS_INLINE blob_(blob_ const& that) noexcept = default; C4_ALWAYS_INLINE blob_(blob_ && that) noexcept = default; C4_ALWAYS_INLINE blob_& operator=(blob_ && that) noexcept = default; C4_ALWAYS_INLINE blob_& operator=(blob_ const& that) noexcept = default; template::value && std::is_same::type, T>::value, U>::type> C4_ALWAYS_INLINE blob_(blob_ const& that) noexcept : buf(that.buf), len(that.len) {} template::value && std::is_same::type, T>::value, U>::type> C4_ALWAYS_INLINE blob_(blob_ && that) noexcept : buf(that.buf), len(that.len) {} template::value && std::is_same::type, T>::value, U>::type> C4_ALWAYS_INLINE blob_& operator=(blob_ && that) noexcept { buf = that.buf; len = that.len; } template::value && std::is_same::type, T>::value, U>::type> C4_ALWAYS_INLINE blob_& operator=(blob_ const& that) noexcept { buf = that.buf; len = that.len; } C4_ALWAYS_INLINE blob_(void *ptr, size_t n) noexcept : buf(reinterpret_cast(ptr)), len(n) {} C4_ALWAYS_INLINE blob_(void const *ptr, size_t n) noexcept : buf(reinterpret_cast(ptr)), len(n) {} #define _C4_REQUIRE_BLOBTYPE(ty) class=typename std::enable_if<((!detail::is_blob_type::value) && (detail::is_blob_value_type::value)), T>::type template C4_ALWAYS_INLINE blob_(U &var) noexcept : buf(reinterpret_cast(&var)), len(sizeof(U)) {} template C4_ALWAYS_INLINE blob_(U *ptr, size_t n) noexcept : buf(reinterpret_cast(ptr)), len(sizeof(U) * n) { C4_ASSERT(is_aligned(ptr)); } template C4_ALWAYS_INLINE blob_& operator= (U &var) noexcept { buf = reinterpret_cast(&var); len = sizeof(U); return *this; } template C4_ALWAYS_INLINE blob_(U (&arr)[N]) noexcept : buf(reinterpret_cast(arr)), len(sizeof(U) * N) {} template C4_ALWAYS_INLINE blob_& operator= (U (&arr)[N]) noexcept { buf = reinterpret_cast(arr); len = sizeof(U) * N; return *this; } #undef _C4_REQUIRE_BLOBTYPE }; /** an immutable binary blob */ using cblob = blob_; /** a mutable binary blob */ using blob = blob_< byte>; C4_MUST_BE_TRIVIAL_COPY(blob); C4_MUST_BE_TRIVIAL_COPY(cblob); } // namespace c4 #endif // _C4_BLOB_HPP_