userver: utils::TrivialBiMap< BuilderFunc > Class Template Reference
Loading...
Searching...
No Matches
utils::TrivialBiMap< BuilderFunc > Class Template Referencefinal

Bidirectional unordered map for trivial types, including string literals; could be efficiently used as a unordered non-bidirectional map. More...

#include <userver/utils/trivial_map.hpp>

Public Types

using First = typename TypesPair::first_type
 
using Second = typename TypesPair::second_type
 
template<class T >
using MappedTypeFor = std::conditional_t< std::is_convertible_v< T, First >, Second, First >
 

Public Member Functions

constexpr TrivialBiMap (BuilderFunc &&func) noexcept
 
constexpr std::optional< Second > TryFindByFirst (First value) const noexcept
 
constexpr std::optional< First > TryFindBySecond (Second value) const noexcept
 
template<class T >
constexpr std::optional< MappedTypeFor< T > > TryFind (T value) const noexcept
 
constexpr std::optional< Second > TryFindICaseByFirst (std::string_view value) const noexcept
 Case insensitive search for value.
 
constexpr std::optional< First > TryFindICaseBySecond (std::string_view value) const noexcept
 Case insensitive search for value.
 
constexpr std::optional< MappedTypeFor< std::string_view > > TryFindICase (std::string_view value) const noexcept
 Case insensitive search for value that calls either TryFindICaseBySecond or TryFindICaseByFirst.
 
constexpr std::size_t size () const noexcept
 Returns count of Case's in mapping.
 
std::string Describe () const
 
std::string DescribeFirst () const
 
std::string DescribeSecond () const
 
template<typename T >
std::string DescribeByType () const
 

Detailed Description

template<typename BuilderFunc>
class utils::TrivialBiMap< BuilderFunc >

Bidirectional unordered map for trivial types, including string literals; could be efficiently used as a unordered non-bidirectional map.

constexpr utils::TrivialBiMap kToInt = [](auto selector) {
return selector()
.Case("zero", 0)
.Case("one", 1)
.Case("two", 2)
.Case("three", 3)
.Case("four", 4);
};
EXPECT_FALSE(kToInt.TryFind(42));
EXPECT_EQ(kToInt.TryFind("one").value(), 1);
EXPECT_EQ(kToInt.TryFind(2).value(), "two");
EXPECT_EQ(kToInt.TryFind("ten").value_or(-1), -1);
}

utils::TrivialBiMap and utils::TrivialSet are known to outperform std::unordered_map if:

  • there's 32 or less elements in map/set
  • or keys are string literals and all of them differ in length.

Implementation of string search is very efficient due to modern compilers optimize it to a switch by input string length and an integral comparison (rather than a std::memcmp call). In other words, it usually takes O(1) to find the match in the map.

The same story with integral or enum mappings - compiler optimizes them into a switch and it usually takes O(1) to find the match.

enum class Colors { kRed, kOrange, kYellow, kGreen, kBlue, kViolet };
return selector()
.Case(ThirdPartyColor::kRed, Colors::kRed)
.Case(ThirdPartyColor::kOrange, Colors::kOrange)
.Case(ThirdPartyColor::kYellow, Colors::kYellow)
.Case(ThirdPartyColor::kGreen, Colors::kGreen)
.Case(ThirdPartyColor::kBlue, Colors::kBlue)
.Case(ThirdPartyColor::kViolet, Colors::kViolet);
};
TEST(TrivialBiMap, EnumToEnum) {
EXPECT_EQ(kColorSwitch.TryFind(ThirdPartyColor::kRed).value(), Colors::kRed);
EXPECT_EQ(kColorSwitch.TryFind(ThirdPartyColor::kBlue).value(),
Colors::kBlue);
EXPECT_EQ(kColorSwitch.TryFind(Colors::kGreen).value(),
ThirdPartyColor::kGreen);
EXPECT_EQ(kColorSwitch.TryFind(Colors::kOrange).value(),
ThirdPartyColor::kOrange);
}

For a single value Case statements see utils::TrivialSet.

Definition at line 487 of file trivial_map.hpp.

Member Typedef Documentation

◆ First

template<typename BuilderFunc >
using utils::TrivialBiMap< BuilderFunc >::First = typename TypesPair::first_type

Definition at line 492 of file trivial_map.hpp.

◆ MappedTypeFor

template<typename BuilderFunc >
template<class T >
using utils::TrivialBiMap< BuilderFunc >::MappedTypeFor = std::conditional_t<std::is_convertible_v<T, First>, Second, First>

Returns Second if T is convertible to First, otherwise returns Second type.

Definition at line 498 of file trivial_map.hpp.

◆ Second

template<typename BuilderFunc >
using utils::TrivialBiMap< BuilderFunc >::Second = typename TypesPair::second_type

Definition at line 493 of file trivial_map.hpp.

Constructor & Destructor Documentation

◆ TrivialBiMap()

template<typename BuilderFunc >
constexpr utils::TrivialBiMap< BuilderFunc >::TrivialBiMap ( BuilderFunc &&  func)
inlineconstexprnoexcept

Definition at line 501 of file trivial_map.hpp.

Member Function Documentation

◆ Describe()

template<typename BuilderFunc >
std::string utils::TrivialBiMap< BuilderFunc >::Describe ( ) const
inline

Returns a string of comma separated quoted values of Case parameters.

Example: "('a', '1'), ('b', '2'), ('c', '3')"

Parameters of Case should be formattable.

Definition at line 584 of file trivial_map.hpp.

◆ DescribeByType()

template<typename BuilderFunc >
template<typename T >
std::string utils::TrivialBiMap< BuilderFunc >::DescribeByType ( ) const
inline

Returns a string of comma separated quoted values of Case parameters that matches by type.

Example: "'1', '2', '3'"

Corresponding Case must be formattable

Definition at line 615 of file trivial_map.hpp.

◆ DescribeFirst()

template<typename BuilderFunc >
std::string utils::TrivialBiMap< BuilderFunc >::DescribeFirst ( ) const
inline

Returns a string of comma separated quoted values of first Case parameters.

Example: "'a', 'b', 'c'"

First parameters of Case should be formattable.

Definition at line 594 of file trivial_map.hpp.

◆ DescribeSecond()

template<typename BuilderFunc >
std::string utils::TrivialBiMap< BuilderFunc >::DescribeSecond ( ) const
inline

Returns a string of comma separated quoted values of second Case parameters.

Example: "'1', '2', '3'"

Second parameters of Case should be formattable.

Definition at line 604 of file trivial_map.hpp.

◆ size()

template<typename BuilderFunc >
constexpr std::size_t utils::TrivialBiMap< BuilderFunc >::size ( ) const
inlineconstexprnoexcept

Returns count of Case's in mapping.

Definition at line 575 of file trivial_map.hpp.

◆ TryFind()

template<typename BuilderFunc >
template<class T >
constexpr std::optional< MappedTypeFor< T > > utils::TrivialBiMap< BuilderFunc >::TryFind ( value) const
inlineconstexprnoexcept

Definition at line 526 of file trivial_map.hpp.

◆ TryFindByFirst()

template<typename BuilderFunc >
constexpr std::optional< Second > utils::TrivialBiMap< BuilderFunc >::TryFindByFirst ( First  value) const
inlineconstexprnoexcept

Definition at line 513 of file trivial_map.hpp.

◆ TryFindBySecond()

template<typename BuilderFunc >
constexpr std::optional< First > utils::TrivialBiMap< BuilderFunc >::TryFindBySecond ( Second  value) const
inlineconstexprnoexcept

Definition at line 519 of file trivial_map.hpp.

◆ TryFindICase()

template<typename BuilderFunc >
constexpr std::optional< MappedTypeFor< std::string_view > > utils::TrivialBiMap< BuilderFunc >::TryFindICase ( std::string_view  value) const
inlineconstexprnoexcept

Case insensitive search for value that calls either TryFindICaseBySecond or TryFindICaseByFirst.

Definition at line 560 of file trivial_map.hpp.

◆ TryFindICaseByFirst()

template<typename BuilderFunc >
constexpr std::optional< Second > utils::TrivialBiMap< BuilderFunc >::TryFindICaseByFirst ( std::string_view  value) const
inlineconstexprnoexcept

Case insensitive search for value.

For efficiency reasons, first parameter in Case() should be lower case string literal.

Definition at line 542 of file trivial_map.hpp.

◆ TryFindICaseBySecond()

template<typename BuilderFunc >
constexpr std::optional< First > utils::TrivialBiMap< BuilderFunc >::TryFindICaseBySecond ( std::string_view  value) const
inlineconstexprnoexcept

Case insensitive search for value.

For efficiency reasons, second parameter in Case() should be lower case string literal.

Definition at line 552 of file trivial_map.hpp.


The documentation for this class was generated from the following file: