1
0
forked from Alepha/Alepha

Invariant gadget.

This commit is contained in:
2024-08-08 17:16:37 -04:00
parent 307175b616
commit 322bf65400
4 changed files with 110 additions and 0 deletions

View File

@ -39,6 +39,7 @@ add_subdirectory( Exception.test )
add_subdirectory( word_wrap.test )
add_subdirectory( string_algorithms.test )
add_subdirectory( template_for.test )
add_subdirectory( Invariant.test )
add_subdirectory( tuplize_args.test )
add_subdirectory( Thread.test )
add_subdirectory( assertion.test )

44
Invariant.h Normal file
View File

@ -0,0 +1,44 @@
static_assert( __cplusplus > 2023'00 );
#pragma once
#include <Alepha/Alepha.h>
#include <cassert>
namespace Alepha::Hydrogen ::detail:: Invariant_m
{
inline namespace exports
{
template< typename T >
class Invariant
{
private:
const T *this_;
void
check() const
{
assert( this_->invariant() );
}
public:
~Invariant()
{
check();
}
explicit
Invariant( const T *const this_ )
: this_( this_ )
{
check();
}
};
}
}
namespace Alepha::Hydrogen::inline exports::inline Invariant_m
{
using namespace detail::Invariant_m::exports;
}

64
Invariant.test/0.cc Normal file
View File

@ -0,0 +1,64 @@
static_assert( __cplusplus > 2023'00 );
#include "../Invariant.h"
#include <Alepha/Testing/TableTest.h>
#include <Alepha/Testing/test.h>
static auto init= Alepha::Utility::enroll <=[]
{
using namespace Alepha::Testing::exports;
"Invariant basic test"_test <=[]
{
struct ItIsFine {};
struct FakeVector
{
int size= 0;
int capacity= 0;
int *data= nullptr;
bool
invariant() const
{
return true
and ( capacity >= size )
and ( capacity < 10 )
and ( capacity == 0 or data != nullptr )
;
}
void
push_back( const int x )
{
Alepha::Invariant inv{ this };
if( size == capacity )
{
// Not fully exception safe, but just
// ignore that...
const int newCapacity= capacity * 2 + 1;
int *const data2= new int [ newCapacity ];
if( capacity > 8 ) throw ItIsFine{};
std::copy( data, data + size, data2 );
capacity= newCapacity;
delete [] data;
data= data2;
}
assert( size < capacity );
data[ size++ ]= x;
}
};
FakeVector v;
for( int i= 0; i < 4; ++i ) try
{
v.push_back( i );
}
catch( const ItIsFine & ) {} // It's fine!
};
};

View File

@ -0,0 +1 @@
unit_test( 0 )