// Protocol Buffers - Google's data interchange format // Copyright 2008 Google Inc. All rights reserved. // https://developers.google.com/protocol-buffers/ // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // This file defines the map container and its helpers to support protobuf maps. // // The Map and MapIterator types are provided by this header file. // Please avoid using other types defined here, unless they are public // types within Map or MapIterator, such as Map::value_type. #ifndef GOOGLE_PROTOBUF_MAP_H__ #define GOOGLE_PROTOBUF_MAP_H__ #include <functional> #include <initializer_list> #include <iterator> #include <limits> // To support Visual Studio 2008 #include <map> #include <string> #include <type_traits> #include <utility> #if defined(__cpp_lib_string_view) #include <string_view> #endif // defined(__cpp_lib_string_view) #if !defined(GOOGLE_PROTOBUF_NO_RDTSC) && defined(__APPLE__) #include <mach/mach_time.h> #endif #include <google/protobuf/stubs/common.h> #include <google/protobuf/arena.h> #include <google/protobuf/generated_enum_util.h> #include <google/protobuf/map_type_handler.h> #include <google/protobuf/port.h> #include <google/protobuf/stubs/hash.h> #ifdef SWIG #error "You cannot SWIG proto headers" #endif // Must be included last. #include <google/protobuf/port_def.inc> namespace google { namespace protobuf { template <typename Key, typename T> class Map; class MapIterator; template <typename Enum> struct is_proto_enum; namespace internal { template <typename Derived, typename Key, typename T, WireFormatLite::FieldType key_wire_type, WireFormatLite::FieldType value_wire_type> class MapFieldLite; template <typename Derived, typename Key, typename T, WireFormatLite::FieldType key_wire_type, WireFormatLite::FieldType value_wire_type> class MapField; template <typename Key, typename T> class TypeDefinedMapFieldBase; class DynamicMapField; class GeneratedMessageReflection; // re-implement std::allocator to use arena allocator for memory allocation. // Used for Map implementation. Users should not use this class // directly. template <typename U> class MapAllocator { … }; KeyForTree; // Default case: Not transparent. // We use std::hash<key_type>/std::less<key_type> and all the lookup functions // only accept `key_type`. template <typename key_type> struct TransparentSupport { … }; #if defined(__cpp_lib_string_view) // If std::string_view is available, we add transparent support for std::string // keys. We use std::hash<std::string_view> as it supports the input types we // care about. The lookup functions accept arbitrary `K`. This will include any // key type that is convertible to std::string_view. template <> struct TransparentSupport<std::string> { … }; #endif // defined(__cpp_lib_string_view) TreeForMap; inline bool TableEntryIsEmpty(void* const* table, size_t b) { … } inline bool TableEntryIsNonEmptyList(void* const* table, size_t b) { … } inline bool TableEntryIsTree(void* const* table, size_t b) { … } inline bool TableEntryIsList(void* const* table, size_t b) { … } // This captures all numeric types. inline size_t MapValueSpaceUsedExcludingSelfLong(bool) { … } inline size_t MapValueSpaceUsedExcludingSelfLong(const std::string& str) { … } template <typename T, typename = decltype(std::declval<const T&>().SpaceUsedLong())> size_t MapValueSpaceUsedExcludingSelfLong(const T& message) { … } constexpr size_t kGlobalEmptyTableSize = …; PROTOBUF_EXPORT extern void* const kGlobalEmptyTable[kGlobalEmptyTableSize]; // Space used for the table, trees, and nodes. // Does not include the indirect space used. Eg the data of a std::string. template <typename Key> PROTOBUF_NOINLINE size_t SpaceUsedInTable(void** table, size_t num_buckets, size_t num_elements, size_t sizeof_node) { … } template <typename Map, typename = typename std::enable_if< !std::is_scalar<typename Map::key_type>::value || !std::is_scalar<typename Map::mapped_type>::value>::type> size_t SpaceUsedInValues(const Map* map) { … } inline size_t SpaceUsedInValues(const void*) { … } } // namespace internal // This is the class for Map's internal value_type. Instead of using // std::pair as value_type, we use this class which provides us more control of // its process of construction and destruction. template <typename Key, typename T> struct PROTOBUF_ATTRIBUTE_STANDALONE_DEBUG MapPair { … }; // Map is an associative container type used to store protobuf map // fields. Each Map instance may or may not use a different hash function, a // different iteration order, and so on. E.g., please don't examine // implementation details to decide if the following would work: // Map<int, int> m0, m1; // m0[0] = m1[0] = m0[1] = m1[1] = 0; // assert(m0.begin()->first == m1.begin()->first); // Bug! // // Map's interface is similar to std::unordered_map, except that Map is not // designed to play well with exceptions. template <typename Key, typename T> class Map { … }; } // namespace protobuf } // namespace google #include <google/protobuf/port_undef.inc> #endif // GOOGLE_PROTOBUF_MAP_H__