You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

map_entry_lite.h 31 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734
  1. // Protocol Buffers - Google's data interchange format
  2. // Copyright 2008 Google Inc. All rights reserved.
  3. // https://developers.google.com/protocol-buffers/
  4. //
  5. // Redistribution and use in source and binary forms, with or without
  6. // modification, are permitted provided that the following conditions are
  7. // met:
  8. //
  9. // * Redistributions of source code must retain the above copyright
  10. // notice, this list of conditions and the following disclaimer.
  11. // * Redistributions in binary form must reproduce the above
  12. // copyright notice, this list of conditions and the following disclaimer
  13. // in the documentation and/or other materials provided with the
  14. // distribution.
  15. // * Neither the name of Google Inc. nor the names of its
  16. // contributors may be used to endorse or promote products derived from
  17. // this software without specific prior written permission.
  18. //
  19. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  22. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  23. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  25. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  26. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  29. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. #ifndef GOOGLE_PROTOBUF_MAP_ENTRY_LITE_H__
  31. #define GOOGLE_PROTOBUF_MAP_ENTRY_LITE_H__
  32. #include <assert.h>
  33. #include <algorithm>
  34. #include <string>
  35. #include <utility>
  36. #include <google/protobuf/stubs/casts.h>
  37. #include <google/protobuf/io/coded_stream.h>
  38. #include <google/protobuf/arena.h>
  39. #include <google/protobuf/port.h>
  40. #include <google/protobuf/arenastring.h>
  41. #include <google/protobuf/generated_message_util.h>
  42. #include <google/protobuf/map.h>
  43. #include <google/protobuf/map_type_handler.h>
  44. #include <google/protobuf/parse_context.h>
  45. #include <google/protobuf/wire_format_lite.h>
  46. // Must be included last.
  47. #include <google/protobuf/port_def.inc>
  48. #ifdef SWIG
  49. #error "You cannot SWIG proto headers"
  50. #endif
  51. namespace google
  52. {
  53. namespace protobuf
  54. {
  55. namespace internal
  56. {
  57. template<typename Derived, typename Key, typename Value, WireFormatLite::FieldType kKeyFieldType, WireFormatLite::FieldType kValueFieldType>
  58. class MapEntry;
  59. template<typename Derived, typename Key, typename Value, WireFormatLite::FieldType kKeyFieldType, WireFormatLite::FieldType kValueFieldType>
  60. class MapFieldLite;
  61. } // namespace internal
  62. } // namespace protobuf
  63. } // namespace google
  64. namespace google
  65. {
  66. namespace protobuf
  67. {
  68. namespace internal
  69. {
  70. // MoveHelper::Move is used to set *dest. It copies *src, or moves it (in
  71. // the C++11 sense), or swaps it. *src is left in a sane state for
  72. // subsequent destruction, but shouldn't be used for anything.
  73. template<bool is_enum, bool is_message, bool is_stringlike, typename T>
  74. struct MoveHelper
  75. { // primitives
  76. static void Move(T* src, T* dest)
  77. {
  78. *dest = *src;
  79. }
  80. };
  81. template<bool is_message, bool is_stringlike, typename T>
  82. struct MoveHelper<true, is_message, is_stringlike, T>
  83. { // enums
  84. static void Move(T* src, T* dest)
  85. {
  86. *dest = *src;
  87. }
  88. // T is an enum here, so allow conversions to and from int.
  89. static void Move(T* src, int* dest)
  90. {
  91. *dest = static_cast<int>(*src);
  92. }
  93. static void Move(int* src, T* dest)
  94. {
  95. *dest = static_cast<T>(*src);
  96. }
  97. };
  98. template<bool is_stringlike, typename T>
  99. struct MoveHelper<false, true, is_stringlike, T>
  100. { // messages
  101. static void Move(T* src, T* dest)
  102. {
  103. dest->Swap(src);
  104. }
  105. };
  106. template<typename T>
  107. struct MoveHelper<false, false, true, T>
  108. { // strings and similar
  109. static void Move(T* src, T* dest)
  110. {
  111. *dest = std::move(*src);
  112. }
  113. };
  114. // MapEntryImpl is used to implement parsing and serialization of map entries.
  115. // It uses Curious Recursive Template Pattern (CRTP) to provide the type of
  116. // the eventual code to the template code.
  117. template<typename Derived, typename Base, typename Key, typename Value, WireFormatLite::FieldType kKeyFieldType, WireFormatLite::FieldType kValueFieldType>
  118. class MapEntryImpl : public Base
  119. {
  120. public:
  121. typedef MapEntryFuncs<Key, Value, kKeyFieldType, kValueFieldType> Funcs;
  122. protected:
  123. // Provide utilities to parse/serialize key/value. Provide utilities to
  124. // manipulate internal stored type.
  125. typedef MapTypeHandler<kKeyFieldType, Key> KeyTypeHandler;
  126. typedef MapTypeHandler<kValueFieldType, Value> ValueTypeHandler;
  127. // Define internal memory layout. Strings and messages are stored as
  128. // pointers, while other types are stored as values.
  129. typedef typename KeyTypeHandler::TypeOnMemory KeyOnMemory;
  130. typedef typename ValueTypeHandler::TypeOnMemory ValueOnMemory;
  131. // Enum type cannot be used for MapTypeHandler::Read. Define a type
  132. // which will replace Enum with int.
  133. typedef typename KeyTypeHandler::MapEntryAccessorType KeyMapEntryAccessorType;
  134. typedef
  135. typename ValueTypeHandler::MapEntryAccessorType ValueMapEntryAccessorType;
  136. // Constants for field number.
  137. static const int kKeyFieldNumber = 1;
  138. static const int kValueFieldNumber = 2;
  139. // Constants for field tag.
  140. static const uint8_t kKeyTag =
  141. GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kKeyFieldNumber, KeyTypeHandler::kWireType);
  142. static const uint8_t kValueTag = GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(
  143. kValueFieldNumber, ValueTypeHandler::kWireType
  144. );
  145. static const size_t kTagSize = 1;
  146. public:
  147. // Work-around for a compiler bug (see repeated_field.h).
  148. typedef void MapEntryHasMergeTypeTrait;
  149. typedef Derived EntryType;
  150. typedef Key EntryKeyType;
  151. typedef Value EntryValueType;
  152. static const WireFormatLite::FieldType kEntryKeyFieldType = kKeyFieldType;
  153. static const WireFormatLite::FieldType kEntryValueFieldType = kValueFieldType;
  154. constexpr MapEntryImpl() :
  155. key_(KeyTypeHandler::Constinit()),
  156. value_(ValueTypeHandler::Constinit()),
  157. _has_bits_{}
  158. {
  159. }
  160. explicit MapEntryImpl(Arena* arena) :
  161. Base(arena),
  162. key_(KeyTypeHandler::Constinit()),
  163. value_(ValueTypeHandler::Constinit()),
  164. _has_bits_{}
  165. {
  166. }
  167. ~MapEntryImpl() override
  168. {
  169. if (Base::GetArenaForAllocation() != nullptr)
  170. return;
  171. KeyTypeHandler::DeleteNoArena(key_);
  172. ValueTypeHandler::DeleteNoArena(value_);
  173. }
  174. // accessors ======================================================
  175. virtual inline const KeyMapEntryAccessorType& key() const
  176. {
  177. return KeyTypeHandler::GetExternalReference(key_);
  178. }
  179. virtual inline const ValueMapEntryAccessorType& value() const
  180. {
  181. return ValueTypeHandler::DefaultIfNotInitialized(value_);
  182. }
  183. inline KeyMapEntryAccessorType* mutable_key()
  184. {
  185. set_has_key();
  186. return KeyTypeHandler::EnsureMutable(&key_, Base::GetArenaForAllocation());
  187. }
  188. inline ValueMapEntryAccessorType* mutable_value()
  189. {
  190. set_has_value();
  191. return ValueTypeHandler::EnsureMutable(&value_, Base::GetArenaForAllocation());
  192. }
  193. // implements MessageLite =========================================
  194. // MapEntryImpl is for implementation only and this function isn't called
  195. // anywhere. Just provide a fake implementation here for MessageLite.
  196. std::string GetTypeName() const override
  197. {
  198. return "";
  199. }
  200. void CheckTypeAndMergeFrom(const MessageLite& other) override
  201. {
  202. MergeFromInternal(*::google::protobuf::internal::DownCast<const Derived*>(&other));
  203. }
  204. const char* _InternalParse(const char* ptr, ParseContext* ctx) final
  205. {
  206. while (!ctx->Done(&ptr))
  207. {
  208. uint32_t tag;
  209. ptr = ReadTag(ptr, &tag);
  210. GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
  211. if (tag == kKeyTag)
  212. {
  213. set_has_key();
  214. KeyMapEntryAccessorType* key = mutable_key();
  215. ptr = KeyTypeHandler::Read(ptr, ctx, key);
  216. if (!Derived::ValidateKey(key))
  217. return nullptr;
  218. }
  219. else if (tag == kValueTag)
  220. {
  221. set_has_value();
  222. ValueMapEntryAccessorType* value = mutable_value();
  223. ptr = ValueTypeHandler::Read(ptr, ctx, value);
  224. if (!Derived::ValidateValue(value))
  225. return nullptr;
  226. }
  227. else
  228. {
  229. if (tag == 0 || WireFormatLite::GetTagWireType(tag) ==
  230. WireFormatLite::WIRETYPE_END_GROUP)
  231. {
  232. ctx->SetLastTag(tag);
  233. return ptr;
  234. }
  235. ptr = UnknownFieldParse(tag, static_cast<std::string*>(nullptr), ptr, ctx);
  236. }
  237. GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
  238. }
  239. return ptr;
  240. }
  241. size_t ByteSizeLong() const override
  242. {
  243. size_t size = 0;
  244. size += kTagSize + static_cast<size_t>(KeyTypeHandler::ByteSize(key()));
  245. size += kTagSize + static_cast<size_t>(ValueTypeHandler::ByteSize(value()));
  246. return size;
  247. }
  248. ::uint8_t* _InternalSerialize(
  249. ::uint8_t* ptr, io::EpsCopyOutputStream* stream
  250. ) const override
  251. {
  252. ptr = KeyTypeHandler::Write(kKeyFieldNumber, key(), ptr, stream);
  253. return ValueTypeHandler::Write(kValueFieldNumber, value(), ptr, stream);
  254. }
  255. // Don't override SerializeWithCachedSizesToArray. Use MessageLite's.
  256. int GetCachedSize() const override
  257. {
  258. int size = 0;
  259. size += has_key() ? static_cast<int>(kTagSize) +
  260. KeyTypeHandler::GetCachedSize(key()) :
  261. 0;
  262. size += has_value() ? static_cast<int>(kTagSize) +
  263. ValueTypeHandler::GetCachedSize(value()) :
  264. 0;
  265. return size;
  266. }
  267. bool IsInitialized() const override
  268. {
  269. return ValueTypeHandler::IsInitialized(value_);
  270. }
  271. Base* New(Arena* arena) const override
  272. {
  273. Derived* entry = Arena::CreateMessage<Derived>(arena);
  274. return entry;
  275. }
  276. protected:
  277. // We can't declare this function directly here as it would hide the other
  278. // overload (const Message&).
  279. void MergeFromInternal(const MapEntryImpl& from)
  280. {
  281. if (from._has_bits_[0])
  282. {
  283. if (from.has_key())
  284. {
  285. KeyTypeHandler::EnsureMutable(&key_, Base::GetArenaForAllocation());
  286. KeyTypeHandler::Merge(from.key(), &key_, Base::GetArenaForAllocation());
  287. set_has_key();
  288. }
  289. if (from.has_value())
  290. {
  291. ValueTypeHandler::EnsureMutable(&value_, Base::GetArenaForAllocation());
  292. ValueTypeHandler::Merge(from.value(), &value_, Base::GetArenaForAllocation());
  293. set_has_value();
  294. }
  295. }
  296. }
  297. public:
  298. void Clear() override
  299. {
  300. KeyTypeHandler::Clear(&key_, Base::GetArenaForAllocation());
  301. ValueTypeHandler::Clear(&value_, Base::GetArenaForAllocation());
  302. clear_has_key();
  303. clear_has_value();
  304. }
  305. // Parsing using MergePartialFromCodedStream, above, is not as
  306. // efficient as it could be. This helper class provides a speedier way.
  307. template<typename MapField, typename Map>
  308. class Parser
  309. {
  310. public:
  311. explicit Parser(MapField* mf) :
  312. mf_(mf),
  313. map_(mf->MutableMap())
  314. {
  315. }
  316. ~Parser()
  317. {
  318. if (entry_ != nullptr && entry_->GetArenaForAllocation() == nullptr)
  319. delete entry_;
  320. }
  321. const char* _InternalParse(const char* ptr, ParseContext* ctx)
  322. {
  323. if (PROTOBUF_PREDICT_TRUE(!ctx->Done(&ptr) && *ptr == kKeyTag))
  324. {
  325. ptr = KeyTypeHandler::Read(ptr + 1, ctx, &key_);
  326. if (PROTOBUF_PREDICT_FALSE(!ptr || !Derived::ValidateKey(&key_)))
  327. {
  328. return nullptr;
  329. }
  330. if (PROTOBUF_PREDICT_TRUE(!ctx->Done(&ptr) && *ptr == kValueTag))
  331. {
  332. typename Map::size_type map_size = map_->size();
  333. value_ptr_ = &(*map_)[key_];
  334. if (PROTOBUF_PREDICT_TRUE(map_size != map_->size()))
  335. {
  336. using T =
  337. typename MapIf<ValueTypeHandler::kIsEnum, int*, Value*>::type;
  338. ptr = ValueTypeHandler::Read(ptr + 1, ctx, reinterpret_cast<T>(value_ptr_));
  339. if (PROTOBUF_PREDICT_FALSE(!ptr || !Derived::ValidateValue(value_ptr_)))
  340. {
  341. map_->erase(key_); // Failure! Undo insertion.
  342. return nullptr;
  343. }
  344. if (PROTOBUF_PREDICT_TRUE(ctx->Done(&ptr)))
  345. return ptr;
  346. if (!ptr)
  347. return nullptr;
  348. NewEntry();
  349. ValueMover::Move(value_ptr_, entry_->mutable_value());
  350. map_->erase(key_);
  351. goto move_key;
  352. }
  353. }
  354. else
  355. {
  356. if (!ptr)
  357. return nullptr;
  358. }
  359. NewEntry();
  360. move_key:
  361. KeyMover::Move(&key_, entry_->mutable_key());
  362. }
  363. else
  364. {
  365. if (!ptr)
  366. return nullptr;
  367. NewEntry();
  368. }
  369. ptr = entry_->_InternalParse(ptr, ctx);
  370. if (ptr)
  371. UseKeyAndValueFromEntry();
  372. return ptr;
  373. }
  374. template<typename UnknownType>
  375. const char* ParseWithEnumValidation(const char* ptr, ParseContext* ctx, bool (*is_valid)(int), uint32_t field_num, InternalMetadata* metadata)
  376. {
  377. auto entry = NewEntry();
  378. ptr = entry->_InternalParse(ptr, ctx);
  379. if (!ptr)
  380. return nullptr;
  381. if (is_valid(entry->value()))
  382. {
  383. UseKeyAndValueFromEntry();
  384. }
  385. else
  386. {
  387. WriteLengthDelimited(field_num, entry->SerializeAsString(), metadata->mutable_unknown_fields<UnknownType>());
  388. }
  389. return ptr;
  390. }
  391. MapEntryImpl* NewEntry()
  392. {
  393. return entry_ = mf_->NewEntry();
  394. }
  395. const Key& key() const
  396. {
  397. return key_;
  398. }
  399. const Value& value() const
  400. {
  401. return *value_ptr_;
  402. }
  403. const Key& entry_key() const
  404. {
  405. return entry_->key();
  406. }
  407. const Value& entry_value() const
  408. {
  409. return entry_->value();
  410. }
  411. private:
  412. void UseKeyAndValueFromEntry()
  413. {
  414. // Update key_ in case we need it later (because key() is called).
  415. // This is potentially inefficient, especially if the key is
  416. // expensive to copy (e.g., a long string), but this is a cold
  417. // path, so it's not a big deal.
  418. key_ = entry_->key();
  419. value_ptr_ = &(*map_)[key_];
  420. ValueMover::Move(entry_->mutable_value(), value_ptr_);
  421. }
  422. // After reading a key and value successfully, and inserting that data
  423. // into map_, we are not at the end of the input. This is unusual, but
  424. // allowed by the spec.
  425. bool ReadBeyondKeyValuePair(io::CodedInputStream* input) PROTOBUF_COLD
  426. {
  427. NewEntry();
  428. ValueMover::Move(value_ptr_, entry_->mutable_value());
  429. map_->erase(key_);
  430. KeyMover::Move(&key_, entry_->mutable_key());
  431. const bool result = entry_->MergePartialFromCodedStream(input);
  432. if (result)
  433. UseKeyAndValueFromEntry();
  434. return result;
  435. }
  436. typedef MoveHelper<KeyTypeHandler::kIsEnum, KeyTypeHandler::kIsMessage, KeyTypeHandler::kWireType == WireFormatLite::WIRETYPE_LENGTH_DELIMITED, Key>
  437. KeyMover;
  438. typedef MoveHelper<ValueTypeHandler::kIsEnum, ValueTypeHandler::kIsMessage, ValueTypeHandler::kWireType == WireFormatLite::WIRETYPE_LENGTH_DELIMITED, Value>
  439. ValueMover;
  440. MapField* const mf_;
  441. Map* const map_;
  442. Key key_;
  443. Value* value_ptr_;
  444. MapEntryImpl* entry_ = nullptr;
  445. };
  446. protected:
  447. void set_has_key()
  448. {
  449. _has_bits_[0] |= 0x00000001u;
  450. }
  451. bool has_key() const
  452. {
  453. return (_has_bits_[0] & 0x00000001u) != 0;
  454. }
  455. void clear_has_key()
  456. {
  457. _has_bits_[0] &= ~0x00000001u;
  458. }
  459. void set_has_value()
  460. {
  461. _has_bits_[0] |= 0x00000002u;
  462. }
  463. bool has_value() const
  464. {
  465. return (_has_bits_[0] & 0x00000002u) != 0;
  466. }
  467. void clear_has_value()
  468. {
  469. _has_bits_[0] &= ~0x00000002u;
  470. }
  471. public:
  472. inline Arena* GetArena() const
  473. {
  474. return Base::GetArena();
  475. }
  476. protected: // Needed for constructing tables
  477. KeyOnMemory key_;
  478. ValueOnMemory value_;
  479. uint32_t _has_bits_[1];
  480. private:
  481. friend class ::PROTOBUF_NAMESPACE_ID::Arena;
  482. typedef void InternalArenaConstructable_;
  483. typedef void DestructorSkippable_;
  484. template<typename C, typename K, typename V, WireFormatLite::FieldType, WireFormatLite::FieldType>
  485. friend class internal::MapEntry;
  486. template<typename C, typename K, typename V, WireFormatLite::FieldType, WireFormatLite::FieldType>
  487. friend class internal::MapFieldLite;
  488. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapEntryImpl);
  489. };
  490. template<typename T, typename Key, typename Value, WireFormatLite::FieldType kKeyFieldType, WireFormatLite::FieldType kValueFieldType>
  491. class MapEntryLite : public MapEntryImpl<T, MessageLite, Key, Value, kKeyFieldType, kValueFieldType>
  492. {
  493. public:
  494. typedef MapEntryImpl<T, MessageLite, Key, Value, kKeyFieldType, kValueFieldType>
  495. SuperType;
  496. constexpr MapEntryLite()
  497. {
  498. }
  499. explicit MapEntryLite(Arena* arena) :
  500. SuperType(arena)
  501. {
  502. }
  503. ~MapEntryLite() override
  504. {
  505. MessageLite::_internal_metadata_.template Delete<std::string>();
  506. }
  507. void MergeFrom(const MapEntryLite& other)
  508. {
  509. MergeFromInternal(other);
  510. }
  511. private:
  512. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapEntryLite);
  513. };
  514. // Helpers for deterministic serialization =============================
  515. // Iterator base for MapSorterFlat and MapSorterPtr.
  516. template<typename storage_type>
  517. struct MapSorterIt
  518. {
  519. storage_type* ptr;
  520. MapSorterIt(storage_type* ptr) :
  521. ptr(ptr)
  522. {
  523. }
  524. bool operator==(const MapSorterIt& other) const
  525. {
  526. return ptr == other.ptr;
  527. }
  528. bool operator!=(const MapSorterIt& other) const
  529. {
  530. return !(*this == other);
  531. }
  532. MapSorterIt& operator++()
  533. {
  534. ++ptr;
  535. return *this;
  536. }
  537. MapSorterIt operator++(int)
  538. {
  539. auto other = *this;
  540. ++ptr;
  541. return other;
  542. }
  543. MapSorterIt operator+(int v)
  544. {
  545. return MapSorterIt{ptr + v};
  546. }
  547. };
  548. // MapSorterFlat stores keys inline with pointers to map entries, so that
  549. // keys can be compared without indirection. This type is used for maps with
  550. // keys that are not strings.
  551. template<typename MapT>
  552. class MapSorterFlat
  553. {
  554. public:
  555. using value_type = typename MapT::value_type;
  556. using storage_type = std::pair<typename MapT::key_type, const value_type*>;
  557. // This const_iterator dereferenes to the map entry stored in the sorting
  558. // array pairs. This is the same interface as the Map::const_iterator type,
  559. // and allows generated code to use the same loop body with either form:
  560. // for (const auto& entry : map) { ... }
  561. // for (const auto& entry : MapSorterFlat(map)) { ... }
  562. struct const_iterator : public MapSorterIt<storage_type>
  563. {
  564. using pointer = const typename MapT::value_type*;
  565. using reference = const typename MapT::value_type&;
  566. using MapSorterIt<storage_type>::MapSorterIt;
  567. pointer operator->() const
  568. {
  569. return this->ptr->second;
  570. }
  571. reference operator*() const
  572. {
  573. return *this->operator->();
  574. }
  575. };
  576. explicit MapSorterFlat(const MapT& m) :
  577. size_(m.size()),
  578. items_(size_ ? new storage_type[size_] : nullptr)
  579. {
  580. if (!size_)
  581. return;
  582. storage_type* it = &items_[0];
  583. for (const auto& entry : m)
  584. {
  585. *it++ = {entry.first, &entry};
  586. }
  587. std::sort(&items_[0], &items_[size_], [](const storage_type& a, const storage_type& b)
  588. { return a.first < b.first; });
  589. }
  590. size_t size() const
  591. {
  592. return size_;
  593. }
  594. const_iterator begin() const
  595. {
  596. return {items_.get()};
  597. }
  598. const_iterator end() const
  599. {
  600. return {items_.get() + size_};
  601. }
  602. private:
  603. size_t size_;
  604. std::unique_ptr<storage_type[]> items_;
  605. };
  606. // MapSorterPtr stores and sorts pointers to map entries. This type is used for
  607. // maps with keys that are strings.
  608. template<typename MapT>
  609. class MapSorterPtr
  610. {
  611. public:
  612. using value_type = typename MapT::value_type;
  613. using storage_type = const typename MapT::value_type*;
  614. // This const_iterator dereferenes the map entry pointer stored in the sorting
  615. // array. This is the same interface as the Map::const_iterator type, and
  616. // allows generated code to use the same loop body with either form:
  617. // for (const auto& entry : map) { ... }
  618. // for (const auto& entry : MapSorterPtr(map)) { ... }
  619. struct const_iterator : public MapSorterIt<storage_type>
  620. {
  621. using pointer = const typename MapT::value_type*;
  622. using reference = const typename MapT::value_type&;
  623. using MapSorterIt<storage_type>::MapSorterIt;
  624. pointer operator->() const
  625. {
  626. return *this->ptr;
  627. }
  628. reference operator*() const
  629. {
  630. return *this->operator->();
  631. }
  632. };
  633. explicit MapSorterPtr(const MapT& m) :
  634. size_(m.size()),
  635. items_(size_ ? new storage_type[size_] : nullptr)
  636. {
  637. if (!size_)
  638. return;
  639. storage_type* it = &items_[0];
  640. for (const auto& entry : m)
  641. {
  642. *it++ = &entry;
  643. }
  644. std::sort(&items_[0], &items_[size_], [](const storage_type& a, const storage_type& b)
  645. { return a->first < b->first; });
  646. }
  647. size_t size() const
  648. {
  649. return size_;
  650. }
  651. const_iterator begin() const
  652. {
  653. return {items_.get()};
  654. }
  655. const_iterator end() const
  656. {
  657. return {items_.get() + size_};
  658. }
  659. private:
  660. size_t size_;
  661. std::unique_ptr<storage_type[]> items_;
  662. };
  663. } // namespace internal
  664. } // namespace protobuf
  665. } // namespace google
  666. #include <google/protobuf/port_undef.inc>
  667. #endif // GOOGLE_PROTOBUF_MAP_ENTRY_LITE_H__