Evo C++ Library v0.5.1
maplist.h
Go to the documentation of this file.
1 // Evo C++ Library
2 /* Copyright 2019 Justin Crowell
3 Distributed under the BSD 2-Clause License -- see included file LICENSE.txt for details.
4 */
6 
7 #pragma once
8 #ifndef INCL_evo_maplist_h
9 #define INCL_evo_maplist_h
10 
11 #include "map.h"
12 #include "list.h"
13 #include "strtok.h"
14 
15 namespace evo {
18 
20 
228 template<class TKey, class TValue, class TCompare=Compare<TKey>, class TSize=SizeT>
229 class MapList : public Map<TKey,TValue,TSize> {
230 public:
232 #if defined(_MSC_VER) || defined(EVO_OLDCC) // avoid errors with older compilers and MSVC
234  typedef typename MapBaseType::Size Size;
235  typedef typename MapBaseType::Key Key;
236  typedef typename MapBaseType::Value Value;
237  typedef typename MapBaseType::Item Item;
238  typedef typename MapBaseType::IterKey IterKey;
239  typedef typename MapBaseType::IterItem IterItem;
240 #else
242  using typename Map<TKey,TValue,TSize>::Size;
243  using typename Map<TKey,TValue,TSize>::Key;
244  using typename Map<TKey,TValue,TSize>::Value;
245  using typename Map<TKey,TValue,TSize>::Item;
246  using typename Map<TKey,TValue,TSize>::IterKey;
247  using typename Map<TKey,TValue,TSize>::IterItem;
248 #endif
250  typedef TCompare Compare;
251 
254 
255  using MapBaseType::size_;
256 
259  { }
260 
267  MapList(const MapBaseType& src)
268  { set(src); }
269 
275  MapList(const ThisType& src) : data_(src.data_)
276  { size_ = src.size_; }
277 
280  { }
281 
282 #if defined(EVO_CPP11)
283  using typename MapBaseType::InitPair;
284 
288  MapList(const std::initializer_list<InitPair>& init) : MapList() {
289  assert( init.size() < IntegerT<Size>::MAX );
290  capacitymin((Size)init.size());
291  for (const auto& item : init)
292  add(item.key, item.value);
293  }
294 
298  MapList(ThisType&& src) : data_(std::move(src.data_)) {
299  MapBaseType::size_ = src.MapBaseType::size_;
300  src.MapBaseType::size_ = 0;
301  }
302 
307  ThisType& operator=(ThisType&& src) {
308  data_ = std::move(src.data_);
309  MapBaseType::size_ = src.MapBaseType::size_;
310  src.MapBaseType::size_ = 0;
311  return *this;
312  }
313 #endif
314 
316  const ThisType& asconst() const {
317  return *this;
318  }
319 
320  // SET
321 
323  ThisType& operator=(const MapBaseType& src)
324  { set(src); return *this; }
325 
332  ThisType& operator=(const ThisType& src) {
333  data_.items = src.data_.items;
335  return *this;
336  }
337 
338  ThisType& set() {
339  data_.items.set();
340  MapBaseType::size_ = 0;
341  return *this;
342  }
343 
344  ThisType& set(const MapBaseType& src) {
345  clear();
346  for (typename MapBaseType::Iter iter(src); iter; ++iter)
347  this->get(iter->first) = iter->second;
348  return *this;
349  }
350 
357  ThisType& set(const ThisType& src) {
358  ((Compare&)data_) = (const Compare&)src.data_;
359  data_.items.set(src.data_.items);
360  MapBaseType::size_ = src.size_;
361  return *this;
362  }
363 
364  ThisType& setempty() {
365  data_.items.setempty();
366  MapBaseType::size_ = 0;
367  return *this;
368  }
369 
370  ThisType& clear() {
371  data_.items.clear();
372  MapBaseType::size_ = 0;
373  return *this;
374  }
375 
376  // INFO
377 
378  bool null() const
379  { return data_.items.null(); }
380 
381  bool shared() const
382  { return data_.items.shared(); }
383 
384  Size capacity() const
385  { return data_.items.capacity(); }
386 
387  // COMPARE
388 
389  using MapBaseType::operator==;
390  using MapBaseType::operator!=;
391 
396  bool operator==(const ThisType& map) const
397  { return (this == &map || data_.items == map.data_.items); }
398 
403  bool operator!=(const ThisType& map) const
404  { return (this != &map && data_.items != map.data_.items); }
405 
406  // FIND
407 
409  Iter cbegin() const
410  { return Iter(*this); }
411 
413  Iter cend() const
414  { return Iter(); }
415 
417  IterM begin()
418  { return IterM(*this); }
419 
421  Iter begin() const
422  { return Iter(*this); }
423 
425  IterM end()
426  { return IterM(); }
427 
429  Iter end() const
430  { return Iter(); }
431 
432  bool contains(const Key& key) const {
433  Size pos;
434  return (search(pos, key) != NULL);
435  }
436 
437  const Value* find(const Key& key) const {
438  Size pos;
439  const Item* item = search(pos, key);
440  return (item != NULL ? &item->second : NULL);
441  }
442 
443  Value* findM(const Key& key) {
444  Size pos;
445  const Item* item = search(pos, key);
446  return (item != NULL ? (Value*)&item->second : NULL);
447  }
448 
453  Size findindex(const Key& key) const
454  { Size pos; return (search(pos, key) == NULL ? END : pos); }
455 
457  Iter iter(const Key& key) const {
458  IterKey iterkey;
459  const Item* item = search(iterkey.a, key);
460  return (item != NULL ? Iter(*this, iterkey, (IterItem*)item) : Iter(*this, iterEND));
461  }
462 
464  IterM iterM(const Key& key) {
465  IterKey iterkey;
466  const Item* item = search(iterkey.a, key);
467  return (item != NULL ? IterM(*this, iterkey, (IterItem*)item) : IterM(*this, iterEND));
468  }
469 
470  Item& getitem(const Key& key, bool* created=NULL) {
471  Item* item;
472  Size pos;
473  if ( (item=(Item*)search(pos, key)) == NULL) {
474  item = &data_.items.itemM(data_.items.insertnew(pos));
475  item->first = key;
476  if (created != NULL)
477  *created = true;
479  } else if (created != NULL)
480  *created = false;
481  return *item;
482  }
483 
485  Value& get(const Key& key, bool* created=NULL)
486  { return getitem(key, created).second; }
487 
494  const Item& item(Size index) const
495  { return data_.items.item(index); }
496 
504  Item& itemM(Size index)
505  { return data_.items.itemM(index); }
506 
507  // INFO_SET
508 
510  Value& operator[](const Key& key)
511  { return getitem(key, NULL).second; }
512 
513  ThisType& unshare()
514  { data_.items.unshare(); return *this; }
515 
516  ThisType& capacity(Size size)
517  { data_.items.capacity(size); return *this; }
518 
519  ThisType& capacitymin(Size min)
520  { data_.items.capacitymin(min); return *this; }
521 
522  ThisType& compact()
523  { data_.items.compact(); return *this; }
524 
526  ThisType& reserve(Size size)
527  { capacitymin(this->size_ + size); return *this; }
528 
529  // ADD
530 
531  Item& add(const Key& key, const Value& value, bool update=true) {
532  bool created_val;
533  Item& upditem = getitem(key, &created_val);
534  if (created_val || update)
535  upditem.second = value;
536  return upditem;
537  }
538 
539  Item& add(const Item& item, bool update=true)
540  { return add(item.first, item.second, update); }
541 
542  ThisType& add(const MapBaseType& map, bool update=true) {
543  if (this != &map) {
544  reserve(map.size());
545  for (typename MapBaseType::Iter iter(map); iter; ++iter)
546  add(iter->first, iter->second, update);
547  }
548  return *this;
549  }
550 
551  // REMOVE
552 
553  bool remove(const Key& key) {
554  bool result = false;
555  Size index;
556  if (search(index, key) != NULL) {
557  data_.items.remove(index);
559  result = true;
560  }
561  return result;
562  }
563 
564  bool remove(typename MapBaseType::IterM& iter, IteratorDir dir=iterNONE)
565  { return remove((IterM&)iter, dir); }
566 
567  bool remove(IterM& iter, IteratorDir dir=iterNONE) {
568  if (iter && this == &iter.getParent()) {
569  IterKey& iterkey = iter.getKey();
570  data_.items.remove(iterkey.a);
571  bool nextitem = false;
572  if (--MapBaseType::size_ > 0 && dir != iterNONE) {
573  if (dir == iterRV) {
574  if (iterkey.a > 0)
575  { --iterkey.a; nextitem = true; }
576  } else if (iterkey.a < data_.items.size())
577  nextitem = true;
578  }
579  if (nextitem)
580  iter.setData( (IterItem*)&data_.items.item(iterkey.a) );
581  else
582  iter = iterEND;
583  return true;
584  }
585  return false;
586  }
587 
594  void removeat(Size index) {
595  assert( index < data_.items.size() );
596  data_.items.remove(index);
598  }
599 
600  // ADVANCED
601 
607  const List<Item>& advList() const
608  { return data_.items; }
609 
616  { return data_.items; }
617 
618  // INTERNAL
619 
620  // Iterator support methods
622  void iterInitMutable()
623  { data_.items.iterInitMutable(); }
624  const IterItem* iterFirst(IterKey& key) const
625  { return (IterItem*)data_.items.iterFirst(key.a); }
626  const IterItem* iterNext(IterKey& key) const
627  { return (IterItem*)data_.items.iterNext(key.a); }
628  const IterItem* iterLast(IterKey& key) const
629  { return (IterItem*)data_.items.iterLast(key.a); }
630  const IterItem* iterPrev(IterKey& key) const
631  { return (IterItem*)data_.items.iterPrev(key.a); }
634 protected:
635  const Item* getiter(IterKey& iterkey, const Key& key) const
636  { return search(iterkey.a, key); }
637 
638 private:
639  typedef List<Item> Items;
640 
641  // Use inheritance to reduce size bloat with empty Compare
642  struct Data : public Compare {
643  Items items;
644 
645  Data() {
646  }
647  Data(const Data& data) : Compare(data), items(data.items) {
648  }
649 
650  #if defined(EVO_CPP11)
651  Data(Data&& data) : Compare(std::move((Compare&&)data)), items(std::move(data.items)) {
652  }
653  Data& operator=(Data&& data) {
654  *((Compare*)this) = std::move((Compare&&)data);
655  items = std::move(data.items);
656  return *this;
657  }
658  #endif
659  };
660 
661  Data data_;
662 
663  const Item* search(Size& index, const Key& key) const {
664  int cmp;
665  Size left = 0, right = data_.items.size(), mid = 0;
666  while (left < right) {
667  mid = left + ((right-left) / 2);
668  const Item& item = data_.items.item(mid);
669  cmp = data_.Compare::operator()(key, item.first);
670  if (cmp < 0) {
671  right = mid;
672  } else if (cmp == 0) {
673  index = mid;
674  return &item;
675  } else
676  left = mid + 1;
677  }
678  index = left;
679  return NULL;
680  }
681 };
682 
684 
685 #if defined(INCL_evo_string_h) || defined(DOXYGEN)
686 
691 #endif
692 
694 
695 }
696 #endif
List< Item > & advList()
Advanced: Get internal list.
Definition: maplist.h:615
Iter cend() const
Get iterator at end (const).
Definition: maplist.h:413
ThisType & operator=(const MapBaseType &src)
Assignment operator.
Definition: maplist.h:323
Pair< Key, Value > Item
Item type (key/value pair)
Definition: map.h:137
void removeat(Size index)
Remove item at given position (mutable).
Definition: maplist.h:594
ThisType & compact()
Reduce capacity to fit current size (modifier).
Definition: maplist.h:522
Map< TKey, TValue, TSize > MapBaseType
Map base type
Definition: map.h:133
bool shared() const
Get whether shared.
Definition: maplist.h:381
Size size_
Map size (number of items, automatically updated by concrete set members)
Definition: map.h:180
Evo string tokenizers.
MapList< String, String > StrMapList
MapList using String keys and values.
Definition: maplist.h:690
#define EVO_CONTAINER_TYPE
Identify current class/struct as an EvoContainer.
Definition: meta.h:482
Iter cbegin() const
Get iterator at first item (const).
Definition: maplist.h:409
Size capacity() const
Get map capacity.
Definition: maplist.h:384
~MapList()
Destructor.
Definition: maplist.h:279
MapList(const std::initializer_list< InitPair > &init)
< Used with initializer_list constructor (C++11)
Definition: maplist.h:288
bool operator!=(const ThisType &map) const
Inequality operator.
Definition: maplist.h:403
Random access iterator.
Definition: iter.h:904
Iter iter(const Key &key) const
Find (lookup) iterator for given key (const).
Definition: maplist.h:457
ThisType & operator=(const ThisType &src)
Assignment operator.
Definition: maplist.h:332
ThisType & unshare()
Make data unique by allocating new buffer, if needed (modifier).
Definition: maplist.h:513
ThisType & capacity(Size size)
Set map capacity.
Definition: maplist.h:516
const ThisType & asconst() const
Explicitly use a const reference to this.
Definition: maplist.h:316
MapList(ThisType &&src)
Move constructor (C++11).
Definition: maplist.h:298
bool operator==(const ThisType &map) const
Equality operator.
Definition: maplist.h:396
Value & operator[](const Key &key)
Get item value for key (mutable).
Definition: maplist.h:510
Basic integer type.
Definition: type.h:980
Item & itemM(Size index)
Get item at position (mutable).
Definition: maplist.h:504
ThisType & reserve(Size size)
Reserve space for new items.
Definition: maplist.h:526
TKey Key
Key type.
Definition: map.h:135
Iter begin() const
Get iterator at first item (const).
Definition: maplist.h:421
MapList(const ThisType &src)
Copy constructor.
Definition: maplist.h:275
Item & add(const Key &key, const Value &value, bool update=true)
Add or update using given key and value.
Definition: maplist.h:531
ThisType & setempty()
Set as empty but not null.
Definition: maplist.h:364
Item & getitem(const Key &key, bool *created=NULL)
Get map item for key (mutable).
Definition: maplist.h:470
ThisType & clear()
Clear by removing all items.
Definition: maplist.h:370
String container.
Definition: string.h:674
Size findindex(const Key &key) const
Find (lookup) index for given key (const).
Definition: maplist.h:453
Bidirectional iterator.
Definition: iter.h:611
MapList(const MapBaseType &src)
Copy constructor.
Definition: maplist.h:267
TA first
First value (same as a() and key())
Definition: pair.h:42
const Value & value() const
Get value for pair (second value) (const).
Definition: pair.h:138
Evo List container.
static const EndT END
Special integer value for indicating end of items or no item.
Definition: type.h:1846
MapList()
Constructor.
Definition: maplist.h:258
const List< Item > & advList() const
Advanced: Get internal list (const).
Definition: maplist.h:607
OptionInfoShPtr Value
Value type.
Definition: map.h:136
IteratorDir
Iterator direction value.
Definition: iter.h:27
IterM begin()
Get iterator at first item (mutable).
Definition: maplist.h:417
IterM end()
Get iterator at end.
Definition: maplist.h:425
Reverse iterator direction.
Definition: iter.h:30
IteratorRa< ThisType >::Const Iter
Iterator (const) - IteratorRa.
Definition: maplist.h:252
const Item & item(Size index) const
Get item at position (const).
Definition: maplist.h:494
Evo C++ Library namespace.
Definition: alg.h:11
No iterator direction.
Definition: iter.h:28
SizeT Size
Size type for size values (must be unsigned integer) – default: SizeT.
Definition: map.h:134
const Key & key() const
Get key for pair (first value) (const).
Definition: pair.h:114
Size size() const
Get map size (number of items).
Definition: map.h:272
IterM iterM(const Key &key)
Find (lookup) iterator for given key (mutable).
Definition: maplist.h:464
MapList< TKey, TValue, TCompare, TSize > ThisType
This type.
Definition: maplist.h:249
Map implemented as an ordered list.
Definition: maplist.h:229
ThisType & operator=(ThisType &&src)
Move assignment operator (C++11).
Definition: maplist.h:307
End iterator position.
Definition: iter.h:23
Value * findM(const Key &key)
Find (lookup) value for given key (mutable).
Definition: maplist.h:443
ThisType & capacitymin(Size min)
Set map capacity to at least given minimum.
Definition: maplist.h:519
const Item * getiter(IterKey &iterkey, const Key &key) const
Used by base class to get data to initialize iterator.
Definition: maplist.h:635
Iter end() const
Get iterator at end (const).
Definition: maplist.h:429
Item & add(const Item &item, bool update=true)
Add or update using given item.
Definition: maplist.h:539
Evo Map interface.
const Value * find(const Key &key) const
Find (lookup) value for given key (const).
Definition: maplist.h:437
ThisType & add(const MapBaseType &map, bool update=true)
Add items from given map.
Definition: maplist.h:542
Stores a key/value pair of independent objects or values.
Definition: pair.h:32
IteratorRa< ThisType > IterM
Iterator (mutable) - IteratorRa.
Definition: maplist.h:253
bool contains(const Key &key) const
Get whether map contains the given key.
Definition: maplist.h:432
Associative container holding key/value pairs for fast lookup.
Definition: map.h:129
T & min(T &a, T &b)
Returns lowest of given values.
Definition: alg.h:26
TB second
Second value (same as b() and value())
Definition: pair.h:43
TCompare Compare
Compare type to use
Definition: maplist.h:250
bool null() const
Get whether map is null.
Definition: maplist.h:378