forked from Alepha/Alepha
Get Blob and Buffer building and a bit tested
This commit is contained in:
82
Blob.h
82
Blob.h
@ -2,17 +2,22 @@ static_assert( __cplusplus > 2020'99 );
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Alepha/Alepha.h>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "Buffer.h"
|
||||
#include "swappable.h"
|
||||
#include "stringify.h"
|
||||
#include "Exceptions.h"
|
||||
#include "evaluation_helpers.h"
|
||||
#include "threading.h"
|
||||
#include "Exception.h"
|
||||
//#include "threading.h"
|
||||
#include "error.h"
|
||||
|
||||
namespace Alepha::inline Cavorite ::detail:: blob
|
||||
#include <Alepha/IOStreams/String.h>
|
||||
#include <Alepha/Utility/evaluation_helpers.h>
|
||||
|
||||
namespace Alepha::Hydrogen ::detail:: Blob_m
|
||||
{
|
||||
inline namespace exports
|
||||
{
|
||||
@ -34,28 +39,29 @@ namespace Alepha::inline Cavorite ::detail:: blob
|
||||
}
|
||||
|
||||
using std::begin, std::end;
|
||||
using IOStreams::stringify;
|
||||
|
||||
class exports::DataCarveTooLargeError
|
||||
: public virtual OutOfRangeError
|
||||
: public virtual Buffer_m::OutOfRangeError
|
||||
{
|
||||
public:
|
||||
explicit
|
||||
DataCarveTooLargeError( const void *const location, const std::size_t request, const std::size_t available )
|
||||
: std::out_of_range( "Tried to carve " + stringify( request ) + " bytes from `Blob` object at location "
|
||||
+ stringify( location ) + " which only has " + stringify( avail ) + " bytes allocated." ),
|
||||
+ stringify( location ) + " which only has " + stringify( available ) + " bytes allocated." ),
|
||||
OutOfRangeError( location, request, available )
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
class exports::DataCarveOutOfRangeError
|
||||
: public virtual OutOfRangeError
|
||||
: public virtual Buffer_m::OutOfRangeError
|
||||
{
|
||||
public:
|
||||
explicit
|
||||
DataCarveOutOfRanceError( const void *const location, const std::size_t request, const std::size_t available )
|
||||
DataCarveOutOfRangeError( const void *const location, const std::size_t request, const std::size_t available )
|
||||
: std::out_of_range( "Tried to carve " + stringify( request ) + " bytes from `Blob` object at location "
|
||||
+ stringify( location ) + " which only has " + stringify( avail ) + " bytes allocated." ),
|
||||
+ stringify( location ) + " which only has " + stringify( available ) + " bytes allocated." ),
|
||||
OutOfRangeError( location, request, available )
|
||||
{}
|
||||
};
|
||||
@ -66,25 +72,27 @@ namespace Alepha::inline Cavorite ::detail:: blob
|
||||
private:
|
||||
using IndirectStorage= std::shared_ptr< std::shared_ptr< Blob > >;
|
||||
IndirectStorage storage; // If this is empty, then this `Blob` object doesn't share ownership. This references the shared pool.
|
||||
Buffer buffer;
|
||||
Buffer< Mutable > buffer;
|
||||
std::size_t viewLimit= 0; // TODO: Consider allowing for unrooted sub-buffer views?
|
||||
|
||||
// TODO: Take the `storage` parameter and make it not increment when this ctor is called -- only when the dice roll passes.
|
||||
explicit
|
||||
Blob( IndirectStorage storage, Buffer buffer ) noexcept
|
||||
: storage( evaluate <=[storage= std::move( storage )] () -> IndirectBacking
|
||||
Blob( IndirectStorage storage, Buffer< Mutable > buffer ) noexcept
|
||||
: storage( Utility::evaluate <=[storage= std::move( storage )] () -> IndirectStorage
|
||||
{
|
||||
if( fastRandomBits( C::storageSplitRandomBitDepth ) ) return std::move( storage );
|
||||
if( C::debugSplitSharing ) error() << "Observed a use count of " << storage.use_count() << " when we failed the dice roll." << std::endl;
|
||||
auto split= std::make_shared< std::shared_ptr< Blob > >( *storage );
|
||||
if( C::
|
||||
//if( fastRandomBits( C::storageSplitRandomBitDepth ) )
|
||||
return std::move( storage );
|
||||
//if( C::debugSplitSharing ) error() << "Observed a use count of " << storage.use_count() << " when we failed the dice roll." << std::endl;
|
||||
//auto split= std::make_shared< std::shared_ptr< Blob > >( *storage );
|
||||
//if( C::
|
||||
//return split;
|
||||
}),
|
||||
buffer( buffer )
|
||||
buffer( buffer ),
|
||||
viewLimit( buffer.size() )
|
||||
{}
|
||||
|
||||
public:
|
||||
~Buffer() { reset(); }
|
||||
~Blob() { reset(); }
|
||||
|
||||
auto
|
||||
swap_lens() noexcept
|
||||
@ -106,7 +114,7 @@ namespace Alepha::inline Cavorite ::detail:: blob
|
||||
void
|
||||
reset() noexcept
|
||||
{
|
||||
if( not storage ) delete buffer;
|
||||
if( not storage ) delete [] buffer.byte_data();
|
||||
else storage.reset();
|
||||
|
||||
buffer= {};
|
||||
@ -125,7 +133,7 @@ namespace Alepha::inline Cavorite ::detail:: blob
|
||||
* @note: No data are copied.
|
||||
*/
|
||||
void
|
||||
reset( const std::size_t )
|
||||
reset( const std::size_t size )
|
||||
{
|
||||
Blob tmp{ size };
|
||||
swap( tmp, *this );
|
||||
@ -133,8 +141,8 @@ namespace Alepha::inline Cavorite ::detail:: blob
|
||||
|
||||
// Copy deep copies the data.
|
||||
Blob( const Blob © )
|
||||
: buffer( new std::byte[ copy.buffer.size() ] ),
|
||||
viewLimit( copy.viewLimit )
|
||||
: buffer( new std::byte[ copy.size() ], copy.size() ),
|
||||
viewLimit( copy.size() )
|
||||
{
|
||||
if( C::debugCtors ) error() << "Blob copy invoked." << std::endl;
|
||||
copyData( *this, copy );
|
||||
@ -178,13 +186,13 @@ namespace Alepha::inline Cavorite ::detail:: blob
|
||||
|
||||
explicit
|
||||
Blob( const std::size_t amount )
|
||||
: buffer( new std::byte[ amount ]{} ), // The data must be 0'ed upon allocation.
|
||||
: buffer( new std::byte[ amount ]{}, amount ), // The data must be 0'ed upon allocation.
|
||||
viewLimit( amount )
|
||||
{}
|
||||
|
||||
explicit
|
||||
Blob( const Buffer< Const > b )
|
||||
: Buffer( b.size() )
|
||||
: Blob( b.size() )
|
||||
{
|
||||
copyData( buffer, b );
|
||||
}
|
||||
@ -228,7 +236,7 @@ namespace Alepha::inline Cavorite ::detail:: blob
|
||||
|
||||
// Now we assume that there's a two-layer scheme, so we operate based upon that.
|
||||
|
||||
Blob rv{ storage, Buffer< Mutable >{ buffer, amount } }
|
||||
Blob rv{ storage, Buffer< Mutable >{ buffer, amount } };
|
||||
buffer= buffer + amount;
|
||||
viewLimit-= amount;
|
||||
|
||||
@ -260,7 +268,7 @@ namespace Alepha::inline Cavorite ::detail:: blob
|
||||
template< typename T > void operator []( T ) const= delete;
|
||||
template< typename T > void operator []( T )= delete;
|
||||
|
||||
constexpr std::size_t capacity() const noecept { return buffer.size(); }
|
||||
constexpr std::size_t capacity() const noexcept { return buffer.size(); }
|
||||
|
||||
bool
|
||||
isContiguousWith( const Blob &other ) const & noexcept
|
||||
@ -269,7 +277,7 @@ namespace Alepha::inline Cavorite ::detail:: blob
|
||||
(
|
||||
storage != nullptr
|
||||
and
|
||||
*storage == *other.backing
|
||||
*storage == *other.storage
|
||||
and
|
||||
byte_data() + size() == other.byte_data()
|
||||
);
|
||||
@ -331,7 +339,7 @@ namespace Alepha::inline Cavorite ::detail:: blob
|
||||
bool
|
||||
couldConcatenate( const Buffer< Const > buffer ) const noexcept
|
||||
{
|
||||
return data.size() <= ( capacity() - size() );
|
||||
return buffer.size() <= ( capacity() - size() );
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -372,9 +380,9 @@ namespace Alepha::inline Cavorite ::detail:: blob
|
||||
[[nodiscard]] Buffer< constness >
|
||||
concatenate( const Buffer< constness > data ) noexcept
|
||||
{
|
||||
const auto amount= std::min( capacity - size(), data.size() );
|
||||
const DataWindow< const > fitted{ data, amount };
|
||||
copyData( buffer, + size(), fitted );
|
||||
const auto amount= std::min( capacity() - size(), data.size() );
|
||||
const Buffer< Const > fitted{ data, amount };
|
||||
copyData( buffer + size(), fitted );
|
||||
setSize( size() + amount );
|
||||
return data + amount;
|
||||
}
|
||||
@ -406,7 +414,7 @@ namespace Alepha::inline Cavorite ::detail:: blob
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto amount= concatenate( Buffer< Const >{ blob } ).size()
|
||||
const auto amount= concatenate( Buffer< Const >{ blob } ).size();
|
||||
const auto rv= blob.carveTail( amount );
|
||||
blob.reset();
|
||||
return rv;
|
||||
@ -482,11 +490,11 @@ namespace Alepha::inline Cavorite ::detail:: blob
|
||||
}
|
||||
};
|
||||
|
||||
static_assert( HasCapability< Blob, swappable > );
|
||||
static_assert( detail::swaps::SwapLensable< Blob > );
|
||||
//static_assert( Capability< Blob, swappable > );
|
||||
//static_assert( detail::swaps::SwapLensable< Blob > );
|
||||
}
|
||||
|
||||
namespace Alepha::Cavorite::inline exports::inline blob
|
||||
namespace Alepha::Hydrogen::inline exports::inline Blob_m
|
||||
{
|
||||
using namespace detail::blob::exports;
|
||||
using namespace detail::Blob_m::exports;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user