Rocket.Chat.ReactNative/ios/Pods/Flipper-Folly/folly/experimental/StringKeyedMap.h

205 lines
5.8 KiB
C++

/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// @author: Pavlo Kushnir (pavlo)
#pragma once
#include <initializer_list>
#include <map>
#include <memory>
#include <folly/Range.h>
#include <folly/experimental/StringKeyedCommon.h>
namespace folly {
/**
* Wrapper class for map<string, Value> that can
* perform lookup operations with StringPiece, not only string.
*
* It uses kind of hack: string pointed by StringPiece is copied when
* StringPiece is inserted into map
*/
template <
class Value,
class Compare = std::less<StringPiece>,
class Alloc = std::allocator<std::pair<const StringPiece, Value>>>
class StringKeyedMap : private std::map<StringPiece, Value, Compare, Alloc> {
private:
using Base = std::map<StringPiece, Value, Compare, Alloc>;
public:
typedef typename Base::key_type key_type;
typedef typename Base::mapped_type mapped_type;
typedef typename Base::value_type value_type;
typedef typename Base::key_compare key_compare;
typedef typename Base::allocator_type allocator_type;
typedef typename Base::reference reference;
typedef typename Base::const_reference const_reference;
typedef typename Base::pointer pointer;
typedef typename Base::const_pointer const_pointer;
typedef typename Base::iterator iterator;
typedef typename Base::const_iterator const_iterator;
typedef typename Base::reverse_iterator reverse_iterator;
typedef typename Base::const_reverse_iterator const_reverse_iterator;
typedef typename Base::difference_type difference_type;
typedef typename Base::size_type size_type;
using Base::get_allocator;
// Ctors in the same order as
// http://cplusplus.com/reference/map/map/map/
explicit StringKeyedMap(
const key_compare& comp = key_compare(),
const allocator_type& alloc = allocator_type())
: Base(comp, alloc) {}
explicit StringKeyedMap(const allocator_type& alloc) : Base(alloc) {}
template <class InputIterator>
explicit StringKeyedMap(
InputIterator b,
InputIterator e,
const key_compare& comp = key_compare(),
const allocator_type& alloc = allocator_type())
: Base(comp, alloc) {
for (; b != e; ++b) {
// emplace() will carry the duplication
emplace(b->first, b->second);
}
}
StringKeyedMap(const StringKeyedMap& rhs)
: StringKeyedMap(rhs, rhs.get_allocator()) {}
StringKeyedMap(const StringKeyedMap& rhs, const allocator_type& a)
: StringKeyedMap(rhs.begin(), rhs.end(), rhs.key_comp(), a) {}
StringKeyedMap(StringKeyedMap&& other) noexcept : Base(std::move(other)) {}
StringKeyedMap(StringKeyedMap&& other, const allocator_type& /* a */) noexcept
: Base(std::move(other) /*, a*/ /* not supported by gcc */) {}
StringKeyedMap(
std::initializer_list<value_type> il,
const key_compare& comp = key_compare(),
const allocator_type& alloc = allocator_type())
: StringKeyedMap(il.begin(), il.end(), comp, alloc) {}
StringKeyedMap& operator=(const StringKeyedMap& other) & {
if (this == &other) {
return *this;
}
return *this = StringKeyedMap(other);
}
StringKeyedMap& operator=(StringKeyedMap&& other) & noexcept {
assert(this != &other);
clear();
Base::operator=(std::move(other));
return *this;
}
using Base::begin;
using Base::cbegin;
using Base::cend;
using Base::crbegin;
using Base::crend;
using Base::empty;
using Base::end;
using Base::max_size;
using Base::rbegin;
using Base::rend;
using Base::size;
bool operator==(StringKeyedMap const& other) const {
Base const& lhs = *this;
Base const& rhs = static_cast<Base const&>(other);
return lhs == rhs;
}
// no need for copy/move overload as StringPiece is small struct
mapped_type& operator[](StringPiece key) {
auto it = find(key);
if (it != end()) {
return it->second;
}
// operator[] will create new (key, value) pair
// we need to allocate memory for key
return Base::operator[](stringPieceDup(key, get_allocator()));
}
using Base::at;
using Base::count;
using Base::find;
using Base::lower_bound;
using Base::upper_bound;
template <class... Args>
std::pair<iterator, bool> emplace(StringPiece key, Args&&... args) {
auto it = find(key);
if (it != end()) {
return {it, false};
}
return Base::emplace(
stringPieceDup(key, get_allocator()), std::forward<Args>(args)...);
}
std::pair<iterator, bool> insert(value_type val) {
auto it = find(val.first);
if (it != end()) {
return {it, false};
}
return Base::insert(std::make_pair(
stringPieceDup(val.first, get_allocator()), std::move(val.second)));
}
iterator erase(const_iterator position) {
auto key = position->first;
auto result = Base::erase(position);
stringPieceDel(key, get_allocator());
return result;
}
size_type erase(StringPiece key) {
auto it = find(key);
if (it == end()) {
return 0;
}
erase(it);
return 1;
}
void clear() noexcept {
for (auto& it : *this) {
stringPieceDel(it.first, get_allocator());
}
Base::clear();
}
using Base::swap;
~StringKeyedMap() {
// Here we assume that map doesn't use keys in destructor
for (auto& it : *this) {
stringPieceDel(it.first, get_allocator());
}
}
};
} // namespace folly