#ifndef _C4_BLOB_HPP_ #define _C4_BLOB_HPP_ #include "c4/types.hpp" /** @file blob.hpp Mutable and immutable binary data blobs. */ C4_BEGIN_NAMESPACE(c4) template struct blob_; /** an immutable binary blob */ using cblob = blob_; /** a mutable binary blob */ using blob = blob_< byte>; template struct blob_ { T * buf; size_t len; C4_ALWAYS_INLINE blob_() noexcept : buf(), len() {} 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; // need to sfinae out copy constructors! (why? isn't the above sufficient?) #define _C4_REQUIRE_NOT_SAME class=typename std::enable_if<( ! std::is_same::value) && ( ! std::is_pointer::value), T>::type template C4_ALWAYS_INLINE blob_(U &var) noexcept : buf(reinterpret_cast(&var)), len(sizeof(U)) {} template C4_ALWAYS_INLINE blob_& operator= (U &var) noexcept { buf = reinterpret_cast(&var); len = sizeof(U); return *this; } #undef _C4_REQUIRE_NOT_SAME 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; } template C4_ALWAYS_INLINE blob_(U *ptr, size_t n) noexcept : buf(reinterpret_cast(ptr)), len(sizeof(U) * n) {} 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) {} }; C4_MUST_BE_TRIVIAL_COPY(blob); C4_MUST_BE_TRIVIAL_COPY(cblob); C4_END_NAMESPACE(c4) #endif // _C4_BLOB_HPP_