userver: utils::TrivialBiMap< BuilderFunc > Class Template Reference
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
utils::TrivialBiMap< BuilderFunc > Class Template Referencefinal

#include <userver/utils/trivial_map.hpp>

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)
.Case("fifty five", 55);
};
TEST(TrivialBiMap, StringBasic) {
EXPECT_TRUE(kToInt.TryFind(0));
EXPECT_FALSE(kToInt.TryFind(42));
EXPECT_EQ(kToInt.TryFind("one"), 1);
EXPECT_EQ(kToInt.TryFind("one"), 1);
const std::optional<utils::StringLiteral> res = kToInt.TryFind(2);
ASSERT_TRUE(res);
EXPECT_EQ(*res, "two");
EXPECT_EQ(kToInt.TryFind(2).value_or(utils::StringLiteral{"unknown"}), "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 };
enum ThirdPartyColor { kGreen, kBlue, kViolet, kRed, kOrange, kYellow };
constexpr utils::TrivialBiMap kColorSwitch = [](auto selector) {
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), Colors::kRed);
EXPECT_EQ(kColorSwitch.TryFind(ThirdPartyColor::kBlue), Colors::kBlue);
EXPECT_EQ(kColorSwitch.TryFind(Colors::kGreen), ThirdPartyColor::kGreen);
EXPECT_EQ(kColorSwitch.TryFind(Colors::kOrange), ThirdPartyColor::kOrange);
}

Empty map:

constexpr utils::TrivialBiMap kEmptyMap = [](auto selector) { return selector().template Type<int, int>(); };

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

Definition at line 665 of file trivial_map.hpp.

Classes

class  iterator
 
struct  value_type
 

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, DecayToStringView<First>>, Second, First>
 

Public Member Functions

constexpr TrivialBiMap (BuilderFunc &&func) noexcept
 
constexpr std::optional< Second > TryFindByFirst (DecayToStringView< First > value) const noexcept
 
constexpr std::optional< First > TryFindBySecond (DecayToStringView< 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
 
constexpr value_type GetValuesByIndex (std::size_t index) const
 
constexpr iterator begin () const
 
constexpr iterator end () const
 
constexpr iterator cbegin () const
 
constexpr iterator cend () const
 

Member Typedef Documentation

◆ First

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

Definition at line 669 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, DecayToStringView<First>>, Second, First>

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

Definition at line 680 of file trivial_map.hpp.

◆ Second

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

Definition at line 670 of file trivial_map.hpp.

Constructor & Destructor Documentation

◆ TrivialBiMap()

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

Definition at line 682 of file trivial_map.hpp.

Member Function Documentation

◆ begin()

template<typename BuilderFunc>
iterator utils::TrivialBiMap< BuilderFunc >::begin ( ) const
inlineconstexpr

Definition at line 827 of file trivial_map.hpp.

◆ cbegin()

template<typename BuilderFunc>
iterator utils::TrivialBiMap< BuilderFunc >::cbegin ( ) const
inlineconstexpr

Definition at line 829 of file trivial_map.hpp.

◆ cend()

template<typename BuilderFunc>
iterator utils::TrivialBiMap< BuilderFunc >::cend ( ) const
inlineconstexpr

Definition at line 830 of file trivial_map.hpp.

◆ 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 753 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 784 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 763 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 773 of file trivial_map.hpp.

◆ end()

template<typename BuilderFunc>
iterator utils::TrivialBiMap< BuilderFunc >::end ( ) const
inlineconstexpr

Definition at line 828 of file trivial_map.hpp.

◆ GetValuesByIndex()

template<typename BuilderFunc>
value_type utils::TrivialBiMap< BuilderFunc >::GetValuesByIndex ( std::size_t index) const
inlineconstexpr

Definition at line 792 of file trivial_map.hpp.

◆ size()

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

Returns count of Case's in mapping.

Definition at line 744 of file trivial_map.hpp.

◆ TryFind()

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

Definition at line 701 of file trivial_map.hpp.

◆ TryFindByFirst()

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

Definition at line 692 of file trivial_map.hpp.

◆ TryFindBySecond()

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

Definition at line 696 of file trivial_map.hpp.

◆ TryFindICase()

template<typename BuilderFunc>
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 731 of file trivial_map.hpp.

◆ TryFindICaseByFirst()

template<typename BuilderFunc>
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 717 of file trivial_map.hpp.

◆ TryFindICaseBySecond()

template<typename BuilderFunc>
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 725 of file trivial_map.hpp.


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