120 lines
3.8 KiB
C++
120 lines
3.8 KiB
C++
// Protocol Buffers - Google's data interchange format
|
|
// Copyright 2008 Google Inc. All rights reserved.
|
|
//
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file or at
|
|
// https://developers.google.com/open-source/licenses/bsd
|
|
|
|
#ifndef GOOGLE_PROTOBUF_MAP_FIELD_LITE_H__
|
|
#define GOOGLE_PROTOBUF_MAP_FIELD_LITE_H__
|
|
|
|
#include <cstddef>
|
|
#include <type_traits>
|
|
|
|
#include "absl/log/absl_check.h"
|
|
#include "google/protobuf/internal_visibility.h"
|
|
#include "google/protobuf/io/coded_stream.h"
|
|
#include "google/protobuf/map.h"
|
|
#include "google/protobuf/parse_context.h"
|
|
#include "google/protobuf/port.h"
|
|
#include "google/protobuf/wire_format_lite.h"
|
|
|
|
// Must be included last.
|
|
#include "google/protobuf/port_def.inc"
|
|
|
|
#ifdef SWIG
|
|
#error "You cannot SWIG proto headers"
|
|
#endif
|
|
|
|
namespace google {
|
|
namespace protobuf {
|
|
namespace internal {
|
|
|
|
// This class provides access to map field using generated api. It is used for
|
|
// internal generated message implementation only. Users should never use this
|
|
// directly.
|
|
template <typename Key, typename T>
|
|
class MapFieldLite {
|
|
public:
|
|
typedef Map<Key, T> MapType;
|
|
|
|
constexpr MapFieldLite() : map_() {}
|
|
explicit MapFieldLite(Arena* arena) : map_(arena) {}
|
|
MapFieldLite(ArenaInitialized, Arena* arena) : MapFieldLite(arena) {}
|
|
|
|
MapFieldLite(InternalVisibility, Arena* arena) : map_(arena) {}
|
|
MapFieldLite(InternalVisibility, Arena* arena, const MapFieldLite& from)
|
|
: map_(arena) {
|
|
MergeFrom(from);
|
|
}
|
|
|
|
#ifdef NDEBUG
|
|
~MapFieldLite() { map_.~Map(); }
|
|
#else
|
|
~MapFieldLite() {
|
|
ABSL_DCHECK_EQ(map_.arena(), nullptr);
|
|
// We want to destruct the map in such a way that we can verify
|
|
// that we've done that, but also be sure that we've deallocated
|
|
// everything (as opposed to leaving an allocation behind with no
|
|
// data in it, as would happen if a vector was resize'd to zero.
|
|
// Map::Swap with an empty map accomplishes that.
|
|
decltype(map_) swapped_map(map_.arena());
|
|
map_.InternalSwap(&swapped_map);
|
|
}
|
|
#endif
|
|
// Accessors
|
|
const Map<Key, T>& GetMap() const { return map_; }
|
|
Map<Key, T>* MutableMap() { return &map_; }
|
|
|
|
// Convenient methods for generated message implementation.
|
|
int size() const { return static_cast<int>(map_.size()); }
|
|
void Clear() { return map_.clear(); }
|
|
void MergeFrom(const MapFieldLite& other) {
|
|
internal::MapMergeFrom(map_, other.map_);
|
|
}
|
|
void Swap(MapFieldLite* other) { map_.swap(other->map_); }
|
|
void InternalSwap(MapFieldLite* other) { map_.InternalSwap(&other->map_); }
|
|
|
|
static constexpr size_t InternalGetArenaOffset(
|
|
internal::InternalVisibility access) {
|
|
return PROTOBUF_FIELD_OFFSET(MapFieldLite, map_) +
|
|
decltype(map_)::InternalGetArenaOffset(access);
|
|
}
|
|
|
|
private:
|
|
typedef void DestructorSkippable_;
|
|
|
|
// map_ is inside an anonymous union so we can explicitly control its
|
|
// destruction
|
|
union {
|
|
Map<Key, T> map_;
|
|
};
|
|
|
|
friend class google::protobuf::Arena;
|
|
};
|
|
|
|
// True if IsInitialized() is true for value field in all elements of t. T is
|
|
// expected to be message. It's useful to have this helper here to keep the
|
|
// protobuf compiler from ever having to emit loops in IsInitialized() methods.
|
|
// We want the C++ compiler to inline this or not as it sees fit.
|
|
template <typename Key, typename T>
|
|
bool AllAreInitialized(const MapFieldLite<Key, T>& field) {
|
|
const auto& t = field.GetMap();
|
|
for (typename Map<Key, T>::const_iterator it = t.begin(); it != t.end();
|
|
++it) {
|
|
if (!it->second.IsInitialized()) return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
template <typename MEntry>
|
|
struct MapEntryToMapField : MapEntryToMapField<typename MEntry::SuperType> {};
|
|
|
|
} // namespace internal
|
|
} // namespace protobuf
|
|
} // namespace google
|
|
|
|
#include "google/protobuf/port_undef.inc"
|
|
|
|
#endif // GOOGLE_PROTOBUF_MAP_FIELD_LITE_H__
|