/* * 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. */ #pragma once /** * This file is intended to be included only by F14Map.h. It contains fallback * implementations of F14Map types for platforms that do not support the * required SIMD instructions, based on std::unordered_map. */ #include namespace folly { namespace f14 { namespace detail { template class F14BasicMap : public std::unordered_map { using Super = std::unordered_map; public: using typename Super::pointer; using typename Super::value_type; F14BasicMap() = default; using Super::Super; //// PUBLIC - F14 Extensions bool containsEqualValue(value_type const& value) const { auto slot = this->bucket(value.first); auto e = this->end(slot); for (auto b = this->begin(slot); b != e; ++b) { if (b->first == value.first) { return b->second == value.second; } } return false; } // exact for libstdc++, approximate for others std::size_t getAllocatedMemorySize() const { std::size_t rv = 0; visitAllocationClasses( [&](std::size_t bytes, std::size_t n) { rv += bytes * n; }); return rv; } // exact for libstdc++, approximate for others template void visitAllocationClasses(V&& visitor) const { auto bc = this->bucket_count(); if (bc > 1) { visitor(bc * sizeof(pointer), 1); } if (this->size() > 0) { visitor(sizeof(StdNodeReplica), this->size()); } } template void visitContiguousRanges(V&& visitor) const { for (value_type const& entry : *this) { value_type const* b = std::addressof(entry); visitor(b, b + 1); } } }; } // namespace detail } // namespace f14 template < typename Key, typename Mapped, typename Hasher, typename KeyEqual, typename Alloc> class F14ValueMap : public f14::detail::F14BasicMap { using Super = f14::detail::F14BasicMap; public: using typename Super::value_type; F14ValueMap() = default; using Super::Super; F14ValueMap& operator=(std::initializer_list ilist) { Super::operator=(ilist); return *this; } }; template < typename Key, typename Mapped, typename Hasher, typename KeyEqual, typename Alloc> class F14NodeMap : public f14::detail::F14BasicMap { using Super = f14::detail::F14BasicMap; public: using typename Super::value_type; F14NodeMap() = default; using Super::Super; F14NodeMap& operator=(std::initializer_list ilist) { Super::operator=(ilist); return *this; } }; template < typename Key, typename Mapped, typename Hasher, typename KeyEqual, typename Alloc> class F14VectorMap : public f14::detail::F14BasicMap { using Super = f14::detail::F14BasicMap; public: using typename Super::value_type; F14VectorMap() = default; using Super::Super; F14VectorMap& operator=(std::initializer_list ilist) { Super::operator=(ilist); return *this; } }; template < typename Key, typename Mapped, typename Hasher, typename KeyEqual, typename Alloc> class F14FastMap : public f14::detail::F14BasicMap { using Super = f14::detail::F14BasicMap; public: using typename Super::value_type; F14FastMap() = default; using Super::Super; F14FastMap& operator=(std::initializer_list ilist) { Super::operator=(ilist); return *this; } }; } // namespace folly