forked from Alepha/Alepha
Fix some bugs I discovered in StringMap
I found these in an executable use case.
This commit is contained in:
@ -9,16 +9,29 @@ static_assert( __cplusplus > 2020'99 );
|
|||||||
#include <exception>
|
#include <exception>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
|
#include <Alepha/error.h>
|
||||||
|
|
||||||
#include <Alepha/Algorithm/string_distance.h>
|
#include <Alepha/Algorithm/string_distance.h>
|
||||||
|
|
||||||
|
#include <Alepha/IOStreams/String.h>
|
||||||
|
|
||||||
namespace Alepha::Hydrogen::Utility ::detail:: StringMap_m
|
namespace Alepha::Hydrogen::Utility ::detail:: StringMap_m
|
||||||
{
|
{
|
||||||
|
namespace C
|
||||||
|
{
|
||||||
|
const bool debug= false;
|
||||||
|
const bool debugCompare= false or C::debug;
|
||||||
|
const bool debugInsertion= false or C::debug;
|
||||||
|
}
|
||||||
|
|
||||||
inline namespace exports
|
inline namespace exports
|
||||||
{
|
{
|
||||||
template< typename Value >
|
template< typename Value >
|
||||||
class StringMap;
|
class StringMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using namespace Alepha::Algorithm::exports::string_distance_m;
|
||||||
|
|
||||||
template< typename Value >
|
template< typename Value >
|
||||||
class exports::StringMap
|
class exports::StringMap
|
||||||
{
|
{
|
||||||
@ -27,8 +40,9 @@ namespace Alepha::Hydrogen::Utility ::detail:: StringMap_m
|
|||||||
|
|
||||||
template< typename Self >
|
template< typename Self >
|
||||||
Value &
|
Value &
|
||||||
at_impl( Self &self, const std::string_view key )
|
at_impl( Self &self, const std::string &key )
|
||||||
{
|
{
|
||||||
|
if( C::debugInsertion ) error() << "Map has " << storage.size() << " entries" << std::endl;
|
||||||
if( not storage.contains( key ) )
|
if( not storage.contains( key ) )
|
||||||
{
|
{
|
||||||
const auto closest= std::min_element( begin( storage ), end( storage ),
|
const auto closest= std::min_element( begin( storage ), end( storage ),
|
||||||
@ -36,26 +50,33 @@ namespace Alepha::Hydrogen::Utility ::detail:: StringMap_m
|
|||||||
{
|
{
|
||||||
const auto l= optimalStringDistance( lhs.first, key );
|
const auto l= optimalStringDistance( lhs.first, key );
|
||||||
const auto r= optimalStringDistance( rhs.first, key );
|
const auto r= optimalStringDistance( rhs.first, key );
|
||||||
|
if( C::debugCompare ) error() << "Left value: " << l << " right value: " << r << std::endl;
|
||||||
return l < r;
|
return l < r;
|
||||||
} );
|
} );
|
||||||
|
|
||||||
if( optimalStringDistance( closest.first, key ) < sqrt( key.size() ) )
|
if( closest == end( storage ) ) throw std::out_of_range{ IOStreams::String() << "The key `" << key << "` could not be found." };
|
||||||
|
else if( optimalStringDistance( closest->first, key ) < sqrt( key.size() ) )
|
||||||
{
|
{
|
||||||
throw std::out_of_range{ Utility::String() << "The key `" << key << "` could not be found. Did you mean `"
|
throw std::out_of_range{ IOStreams::String() << "The key `" << key << "` could not be found. Did you mean `"
|
||||||
<< closest.first << "`?" };
|
<< closest->first << "`?" };
|
||||||
}
|
}
|
||||||
throw std::out_of_range{ Utility::String() << "The key `" << key << "` could not be found." };
|
throw std::out_of_range{ IOStreams::String() << "The key `" << key << "` could not be found." };
|
||||||
}
|
}
|
||||||
return storage.at( key );
|
return storage.at( key );
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Value &at( const std::string_view key ) { return at_impl( *this, key ); }
|
Value &at( const std::string & key ) { return at_impl( *this, key ); }
|
||||||
const Value &at( const std::string_view key ) const { return at_impl( *this, key ); }
|
const Value &at( const std::string &key ) const { return at_impl( *this, key ); }
|
||||||
|
|
||||||
bool contains( const std::string_view key ) const { return storage.contains( key ); }
|
bool contains( const std::string &key ) const { return storage.contains( key ); }
|
||||||
|
|
||||||
void insert( const std::string_view key, Value v ) { if( contains( key ) ) storage.insert( { key, std::move( v ) } ); }
|
void
|
||||||
|
insert( const std::string &key, Value v )
|
||||||
|
{
|
||||||
|
if( not contains( key ) ) storage.emplace( key, std::move( v ) );
|
||||||
|
if( C::debugInsertion ) error() << "Map has " << storage.size() << " entries" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user