diff --git a/Atomic/CMakeLists.txt b/Atomic/CMakeLists.txt index beefa7d..912aeff 100644 --- a/Atomic/CMakeLists.txt +++ b/Atomic/CMakeLists.txt @@ -1 +1,2 @@ +add_subdirectory( Dropbox.test ) add_subdirectory( Mailbox.test ) diff --git a/Atomic/Dropbox.h b/Atomic/Dropbox.h index 68c4ff1..d47c7ac 100644 --- a/Atomic/Dropbox.h +++ b/Atomic/Dropbox.h @@ -29,6 +29,26 @@ namespace Alepha::Hydrogen::Atomic ::detail:: Dropbox_m const bool debug= false; const bool debugInterlock= false or C::debug; const bool debugPop= false or C::debug; + const bool debugSSO= false or C::debug; + } + + inline bool + isSSO( const std::string &s ) + { + const auto base= reinterpret_cast< const char * >( &s ); + + if constexpr( C::debugSSO ) + { + error() << "Base is: " << (void *) base << std::endl; + error() << "Data is: " << (void *) s.data() << std::endl; + error() << "Storage base is: " << sizeof( s ) << std::endl; + } + + const bool result= std::less_equal{}( base, s.data() ) + and std::less{}( s.data(), base + sizeof( s ) ); + + if( C::debugSSO and result ) error() << "Found an SSO" << std::endl; + return result; } inline namespace exports @@ -42,13 +62,52 @@ namespace Alepha::Hydrogen::Atomic ::detail:: Dropbox_m using DropboxFinishedCondition= synthetic_exception< struct finished_exception, FinishedCondition, DropboxFinishedException >; using AnyTaggedDropboxFinishedCondition= AnyTagged< DropboxFinishedCondition >; template< typename tag > using TaggedDropboxFinishedCondition= Tagged< DropboxFinishedCondition, tag >; - } - template< typename T > - std::size_t - computeWeight( const T & ) - { - return sizeof( T ); + + // TODO: Move these to somewhere more sensible... + template< typename T > + std::size_t + computeWeight( const T & ) + { + return sizeof( T ); + } + + inline std::size_t + computeWeight( const std::string &s ) + { + if( isSSO( s ) ) return sizeof( s ); + return sizeof( s ) + s.capacity(); + } + + template< typename T > + std::size_t + computeWeight( const std::vector< T > &v ) + { + std::size_t sz= sizeof( v ) + sizeof( T ) * ( v.capacity() - v.size() ); + + for( const auto &i: v ) + { + sz+= computeWeight( sz ); + } + + return sz; + } + + std::size_t + computeWeight( const Concepts::Aggregate auto &agg ) + { + std::size_t rv= 0; + + // This won't account for slack space... but I have to separate out + // the `sizeof` checks from the way `computeWeight` works. It's + // "good enough" for now... + template_for( agg ) <=[&]( const auto &element ) + { + rv+= computeWeight( element ); + }; + + return rv; + } } /*!