forked from Alepha/Alepha
Started to make a StringMap for fuzzy lookup.
It's not done yet. But I want to checkpoint it.
This commit is contained in:
67
Utility/StringMap.h
Normal file
67
Utility/StringMap.h
Normal file
@ -0,0 +1,67 @@
|
||||
static_assert( __cplusplus > 2020'99 );
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Alepha/Alepha.h>
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <exception>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <Alepha/Algorithm/string_distance.h>
|
||||
|
||||
namespace Alepha::Hydrogen::Utility ::detail:: StringMap_m
|
||||
{
|
||||
inline namespace exports
|
||||
{
|
||||
template< typename Value >
|
||||
class StringMap;
|
||||
}
|
||||
|
||||
template< typename Value >
|
||||
class exports::StringMap
|
||||
{
|
||||
private:
|
||||
std::map< std::string, Value > storage;
|
||||
|
||||
template< typename Self >
|
||||
Value &
|
||||
at_impl( Self &self, const std::string_view key )
|
||||
{
|
||||
if( not storage.contains( key ) )
|
||||
{
|
||||
const auto closest= std::min_element( begin( storage ), end( storage ),
|
||||
[&]( const auto &lhs, const auto &rhs )
|
||||
{
|
||||
const auto l= optimalStringDistance( lhs.first, key );
|
||||
const auto r= optimalStringDistance( rhs.first, key );
|
||||
return l < r;
|
||||
} );
|
||||
|
||||
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 `"
|
||||
<< closest.first << "`?" };
|
||||
}
|
||||
throw std::out_of_range{ Utility::String() << "The key `" << key << "` could not be found." };
|
||||
}
|
||||
return storage.at( key );
|
||||
}
|
||||
|
||||
public:
|
||||
Value &at( const std::string_view key ) { return at_impl( *this, key ); }
|
||||
const Value &at( const std::string_view key ) const { return at_impl( *this, key ); }
|
||||
|
||||
bool contains( const std::string_view key ) const { return storage.contains( key ); }
|
||||
|
||||
void insert( const std::string_view key, Value v ) { if( contains( key ) ) storage.insert( { key, std::move( v ) } ); }
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
namespace Alepha::Hydrogen::Utility::inline exports::inline StringMap_m
|
||||
{
|
||||
using namespace detail::StringMap_m::exports;
|
||||
}
|
Reference in New Issue
Block a user