DeSiGNAR  0.5a
Data Structures General Library
set.H
Go to the documentation of this file.
1 /*
2  This file is part of Designar.
3  Copyright (C) 2017 by Alejandro J. Mujica
4 
5  This program is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  Any user request of this software, write to
19 
20  Alejandro Mujica
21 
22  aledrums@gmail.com
23 */
24 
25 # ifndef DSGSET_H
26 # define DSGSET_H
27 
28 # include <array.H>
29 # include <tree.H>
30 # include <hash.H>
31 # include <sort.H>
32 
33 namespace Designar
34 {
35  template <typename Key, class Cmp = std::less<Key>>
36  struct NotEqualKey
37  {
38  Cmp & cmp;
39 
40  NotEqualKey(Cmp & c)
41  : cmp(c)
42  {
43  // empty
44  }
45 
46  NotEqualKey(Cmp && c = Cmp())
47  : cmp(c)
48  {
49  // empty
50  }
51 
52  bool operator () (const Key & a, const Key & b) const
53  {
54  return cmp(a, b) or cmp(b, a);
55  }
56  };
57 
58  template <typename Key, class Cmp = std::less<Key>>
59  struct EqualKey
60  {
61  Cmp & cmp;
62 
63  EqualKey(Cmp & c)
64  : cmp(c)
65  {
66  // empty
67  }
68 
69  EqualKey(Cmp && c = Cmp())
70  : cmp(c)
71  {
72  // empty
73  }
74 
75  bool operator () (const Key & a, const Key & b) const
76  {
77  return not NotEqualKey<Key, Cmp>(cmp)(a, b);
78  }
79  };
80 
81  template <typename Key, class Cmp>
83  {
84  DynArray<Key> & array;
85  Cmp & cmp;
86 
87 
88  protected:
91 
92  lint_t search(const Key & k, lint_t l, lint_t r) const
93  {
94  return binary_search(array, k, l, r, cmp);
95  }
96 
97  public:
99  : array(a), cmp(c), not_equal_key(cmp), equal_key(cmp)
100  {
101  // empty
102  }
103 
104  bool is_sorted() const
105  {
106  return true;
107  }
108 
109  Key * insert(const Key & item)
110  {
111  lint_t pos = search(item, 0, array.size() - 1);
112 
113  if (pos == array.size())
114  return &array.append(item);
115 
116  if (equal_key(item, array.at(pos)))
117  return nullptr;
118 
119  return &array.insert(pos, item);
120  }
121 
122  Key * insert(Key && item)
123  {
124  lint_t pos = search(item, 0, array.size() - 1);
125 
126  if (pos == array.size())
127  return &array.append(std::forward<Key>(item));
128 
129  if (equal_key(item, array.at(pos)))
130  return nullptr;
131 
132  return &array.insert(pos, std::forward<Key>(item));
133  }
134 
135  Key * insert_dup(const Key & item)
136  {
137  lint_t pos = search(item, 0, array.size() - 1);
138 
139  if (pos == array.size())
140  return &array.append(item);
141 
142  return &array.insert(pos, item);
143  }
144 
145  Key * insert_dup(Key && item)
146  {
147  lint_t pos = search(item, 0, array.size() - 1);
148 
149  if (pos == array.size())
150  return &array.append(std::forward<Key>(item));
151 
152  return &array.insert(pos, std::forward<Key>(item));
153  }
154 
155  Key * search_or_insert(const Key & item)
156  {
157  lint_t pos = search(item, 0, array.size() - 1);
158 
159  if (pos == array.size())
160  return &array.append(item);
161 
162  if (equal_key(item, array.at(pos)))
163  return &array[pos];
164 
165  return &array.insert(pos, item);
166  }
167 
168  Key * search_or_insert(Key && item)
169  {
170  lint_t pos = search(item, 0, array.size() - 1);
171 
172  if (pos == array.size())
173  return &array.append(std::forward<Key>(item));
174 
175  if (equal_key(item, array.at(pos)))
176  return &array[pos];
177 
178  return &array.insert(pos, std::forward<Key>(item));
179  }
180 
181  Key remove_pos(nat_t pos)
182  {
183  return array.remove_pos_closing_breach(pos);
184  }
185 
186  const Key & select(nat_t i)
187  {
188  return array.at(i);
189  }
190 
191  nat_t position(const Key & item)
192  {
193  return search(item, 0, array.size() - 1);
194  }
195  };
196 
197  template <typename Key, class Cmp>
199  {
200  DynArray<Key> & array;
201  Cmp & cmp;
202 
203  protected:
206 
207  protected:
208  lint_t search(const Key & k, lint_t l, lint_t r) const
209  {
210  return sequential_search(array, k, l, r, equal_key);
211  }
212 
213  public:
215  : array(a), cmp(c), not_equal_key(cmp), equal_key(cmp)
216  {
217  // empty
218  }
219 
220  bool is_sorted() const
221  {
222  return array.template is_sorted<Cmp>(cmp);
223  }
224 
225  Key * insert(const Key & item)
226  {
227  lint_t pos = search(item, 0, lint_t(array.size()) - 1);
228 
229  if (pos < array.size())
230  return nullptr;
231 
232  return &array.append(item);
233  }
234 
235  Key * insert(Key && item)
236  {
237  lint_t pos = search(item, 0, lint_t(array.size()) - 1);
238 
239  if (pos < array.size())
240  return nullptr;
241 
242  return &array.append(std::forward<Key>(item));
243  }
244 
245  Key * insert_dup(const Key & item)
246  {
247  return &array.append(item);
248  }
249 
250  Key * insert_dup(Key && item)
251  {
252  return &array.append(std::forward<Key>(item));
253  }
254 
255  Key * search_or_insert(const Key & item)
256  {
257  lint_t pos = search(item, 0, lint_t(array.size()) - 1);
258 
259  if (pos < array.size())
260  return &array[pos];
261 
262  return &array.append(item);
263  }
264 
265  Key * search_or_insert(Key && item)
266  {
267  lint_t pos = search(item, 0, lint_t(array.size()) - 1);
268 
269  if (pos < array.size())
270  return &array[pos];
271 
272  return &array.append(std::forward<Key>(item));
273  }
274 
275  Key remove_pos(nat_t pos)
276  {
277  return array.remove_pos(pos);
278  }
279 
280  const Key & select(nat_t i)
281  {
282  quicksort(array, 0, array.size() - 1, cmp);
283  return array.at(i);
284  }
285 
286  nat_t position(const Key & item)
287  {
288  quicksort(array, 0, array.size() - 1, cmp);
289  return search(item, 0, array.size() - 1);
290  }
291  };
292 
293  template <typename Key, class Cmp, class ArraySetOp>
294  class GenArraySet :
295  public ArraySetOp,
296  public ContainerAlgorithms<GenArraySet<Key, Cmp, ArraySetOp>, Key>,
297  public SetAlgorithms<GenArraySet<Key, Cmp, ArraySetOp>, Key>
298  {
299  public:
300  using ItemType = Key;
301  using KeyType = Key;
302  using DataType = Key;
303  using ValueType = Key;
304  using SizeType = nat_t;
305 
307  Cmp & cmp;
308 
309  public:
310  GenArraySet(nat_t cap, Cmp & _cmp)
311  : ArraySetOp(array, _cmp), array(cap), cmp(_cmp)
312  {
313  // empty
314  }
315 
316  GenArraySet(Cmp && _cmp = Cmp())
317  : ArraySetOp(array, _cmp), array(), cmp(_cmp)
318  {
319  // empty
320  }
321 
322  GenArraySet(nat_t cap, Cmp && _cmp = Cmp())
323  : GenArraySet(cap, _cmp)
324  {
325  // empty
326  }
327 
329  : ArraySetOp(array, a.cmp), array(a.array), cmp(a.cmp)
330  {
331  // empty
332  }
333 
335  : GenArraySet()
336  {
337  swap(a);
338  }
339 
340  GenArraySet(const std::initializer_list<Key> &);
341 
342  GenArraySet & operator = (const GenArraySet & a)
343  {
344  if (&a == this)
345  return *this;
346 
347  array = a.array;
348  cmp = a.cmp;
349 
350  return *this;
351  }
352 
353  GenArraySet & operator = (GenArraySet && a)
354  {
355  swap(a);
356  return *this;
357  }
358 
359  void swap(GenArraySet & a)
360  {
361  array.swap(a.array);
362  std::swap(cmp, a.cmp);
363  }
364 
365  Cmp & get_cmp()
366  {
367  return cmp;
368  }
369 
370  const Cmp & get_cmp() const
371  {
372  return cmp;
373  }
374 
375  bool is_empty() const
376  {
377  return array.is_empty();
378  }
379 
380  nat_t size() const
381  {
382  return array.size();
383  }
384 
385  void clear()
386  {
387  array.clear();
388  }
389 
390  Key * append(const Key & k)
391  {
392  return ArraySetOp::insert(k);
393  }
394 
395  Key * append(Key && k)
396  {
397  return ArraySetOp::insert(std::forward<Key>(k));
398  }
399 
400  Key * append_dup(const Key & k)
401  {
402  return ArraySetOp::insert_dup(k);
403  }
404 
405  Key * append_dup(Key && k)
406  {
407  return ArraySetOp::insert_dup(std::forward<Key>(k));
408  }
409 
410  Key * search(const Key & item)
411  {
412  lint_t pos = ArraySetOp::search(item, 0, lint_t(this->size()) - 1);
413 
414  if (pos >= this->size() or ArraySetOp::not_equal_key(item, array.at(pos)))
415  return nullptr;
416 
417  return &array.at(pos);
418  }
419 
420  const Key * search(const Key & item) const
421  {
422  lint_t pos = ArraySetOp::search(item, 0, lint_t(this->size()) - 1);
423 
424  if (pos >= this->size() or ArraySetOp::not_equal_key(item, array.at(pos)))
425  return nullptr;
426 
427  return &array.at(pos);
428  }
429 
430  Key & find(const Key & item)
431  {
432  Key * result = search(item);
433  if (result == nullptr)
434  throw std::domain_error("Item does not exist");
435  return *result;
436  }
437 
438  const Key & find(const Key & item) const
439  {
440  const Key * result = search(item);
441  if (result == nullptr)
442  throw std::domain_error("Item does not exist");
443  return *result;
444  }
445 
446  bool remove(const Key & item)
447  {
448  lint_t pos = ArraySetOp::search(item, 0, lint_t(this->size()) - 1);
449 
450  if (pos >= this->size() or ArraySetOp::not_equal_key(array.at(pos), item))
451  return false;
452 
453  ArraySetOp::remove_pos(pos);
454  return true;
455  }
456 
457  Key & operator [] (nat_t i)
458  {
459  return array[i];
460  }
461 
462  const Key & operator [] (nat_t i) const
463  {
464  return array[i];
465  }
466 
467  class Iterator : public DynArray<Key>::Iterator
468  {
469  using Base = typename DynArray<Key>::Iterator;
470 
471  public:
473  : Base()
474  {
475  // empty
476  }
477 
479  : Base(a.array)
480  {
481  // empty
482  }
483 
484  Iterator(const GenArraySet & a, nat_t c)
485  : Base(a.array, c)
486  {
487  // empty
488  }
489 
490  Iterator(const Iterator & itor)
491  : Base(itor)
492  {
493  // empty
494  }
495 
497  : Iterator()
498  {
499  Base::swap(itor);
500  }
501  };
502 
503  Iterator begin()
504  {
505  return Iterator(*this);
506  }
507 
508  Iterator begin() const
509  {
510  return Iterator(*this);
511  }
512 
513  Iterator end()
514  {
515  return Iterator(*this, size());
516  }
517 
518  Iterator end() const
519  {
520  return Iterator(*this, size());
521  }
522  };
523 
524  template <typename Key, class Cmp, class ArraySetOp>
526  GenArraySet(const std::initializer_list<Key> & l)
527  : GenArraySet(l.size())
528  {
529  for (const Key & item : l)
530  append(item);
531  }
532 
533  template <typename Key, class Cmp = std::less<Key>>
534  class UnsortedArraySet : public GenArraySet<Key, Cmp,
535  UnsortedArraySetOp<Key, Cmp>>
536  {
538  using Base::Base;
539  };
540 
541  template <typename Key, class Cmp = std::less<Key>>
543  public GenArraySet<Key, Cmp, SortedArraySetOp<Key, Cmp>>
544  {
546  using Base::Base;
547  };
548 
549  template <typename Key, class Cmp = std::less<Key>,
550  template <typename, class> class ArrayType = UnsortedArraySet>
551  class ArraySet : public ArrayType<Key, Cmp>
552  {
553  using Base = ArrayType<Key, Cmp>;
554  using Base::Base;
555 
556  public:
557  using ContainerType = ArrayType<Key, Cmp>;
558  };
559 
560  template <typename Key, class Cmp = std::less<Key>,
561  template <typename, class> class TreeType = RankedTreap>
562  class TreeSet : public TreeType<Key, Cmp>
563  {
564  using Base = TreeType<Key, Cmp>;
565  using Base::Base;
566 
567  public:
568  using ContainerType = TreeType<Key, Cmp>;
569  };
570 
571  template <typename Key, class Cmp = std::equal_to<Key>,
572  template <typename, class> class HashTableType = LHashTable>
573  class HashSet : public HashTableType<Key, Cmp>
574  {
575  using Base = HashTableType<Key, Cmp>;
576  using Base::Base;
577 
578  public:
579  using ContainerType = HashTableType<Key, Cmp>;
580  };
581 
582 
583 } // end namespace DeSIGNAR
584 
585 # endif // DSGSET_H
Cmp & cmp
Definition: set.H:61
void quicksort(ArrayType &, lint_t, lint_t, Cmp &)
Definition: sort.H:253
Key * append(Key &&k)
Definition: set.H:395
Key & find(const Key &item)
Definition: set.H:430
T remove_pos_closing_breach(nat_t pos)
Definition: array.H:596
Definition: set.H:59
nat_t position(const Key &item)
Definition: set.H:286
Cmp & cmp
Definition: set.H:307
Iterator begin()
Definition: set.H:503
EqualKey< Key, Cmp > equal_key
Definition: set.H:205
Iterator begin() const
Definition: set.H:508
Key * insert(const Key &item)
Definition: set.H:225
GenArraySet(GenArraySet &&a)
Definition: set.H:334
Definition: set.H:573
Key * insert_dup(const Key &item)
Definition: set.H:245
Definition: setalgorithms.H:36
Key remove_pos(nat_t pos)
Definition: set.H:275
Iterator(const GenArraySet &a)
Definition: set.H:478
nat_t size() const
Definition: set.H:380
SortedArraySetOp(DynArray< Key > &a, Cmp &c)
Definition: set.H:98
NotEqualKey(Cmp &&c=Cmp())
Definition: set.H:46
EqualKey< Key, Cmp > equal_key
Definition: set.H:90
NotEqualKey(Cmp &c)
Definition: set.H:40
lint_t sequential_search(const ArrayType< T > &, const T &, lint_t, lint_t, Cmp &)
Definition: sort.H:125
Cmp & cmp
Definition: set.H:38
Iterator(Iterator &&itor)
Definition: set.H:496
T & insert(nat_t pos, const T &item)
Definition: array.H:520
nat_t size() const
Definition: array.H:467
DynArray< Key > array
Definition: set.H:306
Key * search_or_insert(Key &&item)
Definition: set.H:168
Cmp & get_cmp()
Definition: set.H:365
lint_t search(const Key &k, lint_t l, lint_t r) const
Definition: set.H:92
TreeType< MapKey< Key, Value >, CmpWrapper< Key, Value, Cmp > > ContainerType
Definition: set.H:568
T & at(nat_t i)
Definition: array.H:653
Definition: set.H:551
Definition: hash.H:73
T & append(const T &item)
Definition: array.H:562
const Cmp & get_cmp() const
Definition: set.H:370
T remove_pos(nat_t pos)
Definition: array.H:576
Key * insert_dup(Key &&item)
Definition: set.H:145
Definition: set.H:542
void clear()
Definition: array.H:477
Definition: set.H:534
bool operator()(const Key &a, const Key &b) const
Definition: set.H:52
HashTableType< MapKey< Key, Value >, CmpWrapper< Key, Value, Cmp > > ContainerType
Definition: set.H:579
void swap(GenArraySet &a)
Definition: set.H:359
void swap(DynArray &a)
Definition: array.H:456
Key * append(const Key &k)
Definition: set.H:390
Definition: set.H:198
const Key * search(const Key &item) const
Definition: set.H:420
Definition: set.H:82
Key * insert_dup(Key &&item)
Definition: set.H:250
long long lint_t
Definition: types.H:49
const Key & select(nat_t i)
Definition: set.H:280
Definition: set.H:36
bool is_sorted() const
Definition: set.H:220
Key * search_or_insert(const Key &item)
Definition: set.H:155
Key * append_dup(Key &&k)
Definition: set.H:405
bool is_sorted() const
Definition: set.H:104
Definition: tree.H:102
Definition: containeralgorithms.H:33
Key remove_pos(nat_t pos)
Definition: set.H:181
bool is_empty() const
Definition: array.H:472
GenArraySet(Cmp &&_cmp=Cmp())
Definition: set.H:316
Key * search_or_insert(const Key &item)
Definition: set.H:255
Iterator(const Iterator &itor)
Definition: set.H:490
Iterator end()
Definition: set.H:513
Key * insert(Key &&item)
Definition: set.H:122
Key * insert(const Key &item)
Definition: set.H:109
const Key & find(const Key &item) const
Definition: set.H:438
Key * insert_dup(const Key &item)
Definition: set.H:135
Key * search_or_insert(Key &&item)
Definition: set.H:265
EqualKey(Cmp &c)
Definition: set.H:63
Definition: set.H:294
Iterator(const GenArraySet &a, nat_t c)
Definition: set.H:484
Definition: array.H:32
NotEqualKey< Key, Cmp > not_equal_key
Definition: set.H:204
EqualKey(Cmp &&c=Cmp())
Definition: set.H:69
Definition: set.H:562
Iterator()
Definition: set.H:472
unsigned long int nat_t
Definition: types.H:50
UnsortedArraySetOp(DynArray< Key > &a, Cmp &c)
Definition: set.H:214
NotEqualKey< Key, Cmp > not_equal_key
Definition: set.H:89
GenArraySet(nat_t cap, Cmp &&_cmp=Cmp())
Definition: set.H:322
GenArraySet(const GenArraySet &a)
Definition: set.H:328
Key * append_dup(const Key &k)
Definition: set.H:400
nat_t position(const Key &item)
Definition: set.H:191
const Key & select(nat_t i)
Definition: set.H:186
lint_t search(const Key &k, lint_t l, lint_t r) const
Definition: set.H:208
void clear()
Definition: set.H:385
ArrayType< MapKey< Key, Value >, CmpWrapper< Key, Value, Cmp > > ContainerType
Definition: set.H:557
lint_t binary_search(const ArrayType< T > &, const T &, lint_t, lint_t, Cmp &)
Definition: sort.H:81
Definition: set.H:467
Iterator end() const
Definition: set.H:518
GenArraySet(nat_t cap, Cmp &_cmp)
Definition: set.H:310
Key * search(const Key &item)
Definition: set.H:410
bool is_empty() const
Definition: set.H:375
Key * insert(Key &&item)
Definition: set.H:235