summaryrefslogtreecommitdiff
path: root/libstdc++-v3/include/ext/pb_ds/tag_and_trait.hpp
blob: 5aa78ff6ca3dc9e4f5d95a7a594373628813f26a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
// -*- C++ -*-

// Copyright (C) 2005-2019 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the terms
// of the GNU General Public License as published by the Free Software
// Foundation; either version 3, or (at your option) any later
// version.

// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.

// Permission to use, copy, modify, sell, and distribute this software
// is hereby granted without fee, provided that the above copyright
// notice appears in all copies, and that both that copyright notice
// and this permission notice appear in supporting documentation. None
// of the above authors, nor IBM Haifa Research Laboratories, make any
// representation about the suitability of this software for any
// purpose. It is provided "as is" without express or implied
// warranty.

/**
 * @file tag_and_trait.hpp
 * Contains tags and traits, e.g., ones describing underlying
 * data structures.
 */

#ifndef PB_DS_TAG_AND_TRAIT_HPP
#define PB_DS_TAG_AND_TRAIT_HPP

#include <bits/c++config.h>
#include <ext/pb_ds/detail/type_utils.hpp>

/**
 * @namespace __gnu_pbds
 * @brief GNU extensions for policy-based data structures for public use.
 */
namespace __gnu_pbds
{
  /** @defgroup pbds Policy-Based Data Structures
   *  @ingroup extensions
   *
   *  This is a library of policy-based elementary data structures:
   *  associative containers and priority queues. It is designed for
   *  high-performance, flexibility, semantic safety, and conformance
   *  to the corresponding containers in std (except for some points
   *  where it differs by design).
   *
   *  For details, see:
   *  http://gcc.gnu.org/onlinedocs/libstdc++/ext/pb_ds/index.html
   *
   *  @{
   */

  /**
   *  @defgroup tags Tags
   *  @{   
   */
  /// A trivial iterator tag. Signifies that the iterators has none of
  /// std::iterators's movement abilities.
  struct trivial_iterator_tag
  { };

  /// Prohibit moving trivial iterators.
  typedef void trivial_iterator_difference_type;


  /**
   *  @defgroup invalidation_tags  Invalidation Guarantees
   *  @ingroup tags
   *  @{
   */

  /**
   *  Signifies a basic invalidation guarantee that any iterator,
   *  pointer, or reference to a container object's mapped value type
   *  is valid as long as the container is not modified.
   */
  struct basic_invalidation_guarantee
  { };

  /**
   *  Signifies an invalidation guarantee that includes all those of
   *  its base, and additionally, that any point-type iterator,
   *  pointer, or reference to a container object's mapped value type
   *  is valid as long as its corresponding entry has not be erased,
   *  regardless of modifications to the container object.
   */
  struct point_invalidation_guarantee : public basic_invalidation_guarantee
  { };

  /**
   *  Signifies an invalidation guarantee that includes all those of
   *  its base, and additionally, that any range-type iterator
   *  (including the returns of begin() and end()) is in the correct
   *  relative positions to other range-type iterators as long as its
   *  corresponding entry has not be erased, regardless of
   *  modifications to the container object.
   */
  struct range_invalidation_guarantee : public point_invalidation_guarantee
  { };
  //@}


  /**
   *  @defgroup ds_tags Data Structure Type
   *  @ingroup tags
   *  @{
   */
  /// Base data structure tag.
  struct container_tag
  { };

  /// Basic sequence.
  struct sequence_tag : public container_tag { };

  /// Basic string container, inclusive of strings, ropes, etc.
  struct string_tag : public sequence_tag { };

  /// Basic associative-container.
  struct associative_tag : public container_tag { };

  /// Basic hash structure.
  struct basic_hash_tag : public associative_tag { };

  /// Collision-chaining hash.
  struct cc_hash_tag : public basic_hash_tag { };

  /// General-probing hash.
  struct gp_hash_tag : public basic_hash_tag { };

  /// Basic branch structure.
  struct basic_branch_tag : public associative_tag { };

  /// Basic tree structure.
  struct tree_tag : public basic_branch_tag { };

  /// Red-black tree.
  struct rb_tree_tag : public tree_tag { };

  /// Splay tree.
  struct splay_tree_tag : public tree_tag { };

  /// Ordered-vector tree.
  struct ov_tree_tag : public tree_tag { };

  /// Basic trie structure.
  struct trie_tag : public basic_branch_tag { };

  /// PATRICIA trie.
  struct pat_trie_tag : public trie_tag { };

  /// List-update.
  struct list_update_tag : public associative_tag { };

  /// Basic priority-queue.
  struct priority_queue_tag : public container_tag { };

  /// Pairing-heap.
  struct pairing_heap_tag : public priority_queue_tag { };

  /// Binomial-heap.
  struct binomial_heap_tag : public priority_queue_tag { };

  /// Redundant-counter binomial-heap.
  struct rc_binomial_heap_tag : public priority_queue_tag { };

  /// Binary-heap (array-based).
  struct binary_heap_tag : public priority_queue_tag { };

  /// Thin heap.
  struct thin_heap_tag : public priority_queue_tag { };
  //@}
  //@}


  /**
   *  @defgroup traits Traits
   *  @{
   */

  /**
   *  @brief Represents no type, or absence of type, for template tricks.
   *
   *  In a mapped-policy, indicates that an associative container is a set.
   *
   *  In a list-update policy, indicates that each link does not need
   *  metadata.
   *
   *  In a hash policy, indicates that the combining hash function
   *  is actually a ranged hash function.
   *
   *  In a probe policy, indicates that the combining probe function
   *  is actually a ranged probe function.
   */
  struct null_type { };

  /// A null node updator, indicating that no node updates are required.
  template<typename _Tp1, typename _Tp2, typename _Tp3, typename _Tp4>
    struct null_node_update : public null_type
    { };


  /// Primary template, container traits base.
  template<typename _Tag>
    struct container_traits_base;

  /// Specialization, cc hash.
  template<>
  struct container_traits_base<cc_hash_tag>
  {
    typedef cc_hash_tag 				container_category;
    typedef point_invalidation_guarantee 		invalidation_guarantee;

    enum
      {
	order_preserving = false,
	erase_can_throw = false,
	split_join_can_throw = false,
	reverse_iteration = false
      };
  };

  /// Specialization, gp hash.
  template<>
  struct container_traits_base<gp_hash_tag>
  {
    typedef gp_hash_tag 				container_category;
    typedef basic_invalidation_guarantee 		invalidation_guarantee;

    enum
      {
	order_preserving = false,
	erase_can_throw = false,
	split_join_can_throw = false,
	reverse_iteration = false
      };
  };

  /// Specialization, rb tree.
  template<>
  struct container_traits_base<rb_tree_tag>
  {
    typedef rb_tree_tag 				container_category;
    typedef range_invalidation_guarantee 		invalidation_guarantee;

    enum
      {
	order_preserving = true,
	erase_can_throw = false,
	split_join_can_throw = false,
	reverse_iteration = true
      };
  };

  /// Specialization, splay tree.
  template<>
  struct container_traits_base<splay_tree_tag>
  {
    typedef splay_tree_tag 				container_category;
    typedef range_invalidation_guarantee 		invalidation_guarantee;

    enum
      {
	order_preserving = true,
	erase_can_throw = false,
	split_join_can_throw = false,
	reverse_iteration = true
      };
  };

  /// Specialization, ov tree.
  template<>
  struct container_traits_base<ov_tree_tag>
  {
    typedef ov_tree_tag 				container_category;
    typedef basic_invalidation_guarantee 		invalidation_guarantee;

    enum
      {
	order_preserving = true,
	erase_can_throw = true,
	split_join_can_throw = true,
	reverse_iteration = false
      };
  };

  /// Specialization, pat trie.
  template<>
  struct container_traits_base<pat_trie_tag>
  {
    typedef pat_trie_tag 				container_category;
    typedef range_invalidation_guarantee 		invalidation_guarantee;

    enum
      {
	order_preserving = true,
	erase_can_throw = false,
	split_join_can_throw = true,
	reverse_iteration = true
      };
  };

  /// Specialization, list update.
  template<>
  struct container_traits_base<list_update_tag>
  {
    typedef list_update_tag 				container_category;
    typedef point_invalidation_guarantee 		invalidation_guarantee;

    enum
      {
	order_preserving = false,
	erase_can_throw = false,
	split_join_can_throw = false,
	reverse_iteration = false
      };
  };

  /// Specialization, pairing heap.
  template<>
  struct container_traits_base<pairing_heap_tag>
  {
    typedef pairing_heap_tag 				container_category;
    typedef point_invalidation_guarantee 		invalidation_guarantee;

    enum
      {
	order_preserving = false,
	erase_can_throw = false,
	split_join_can_throw = false,
	reverse_iteration = false
      };
  };

  /// Specialization, thin heap.
  template<>
  struct container_traits_base<thin_heap_tag>
  {
    typedef thin_heap_tag 				container_category;
    typedef point_invalidation_guarantee 		invalidation_guarantee;

    enum
      {
	order_preserving = false,
	erase_can_throw = false,
	split_join_can_throw = false,
	reverse_iteration = false
      };
  };

  /// Specialization, binomial heap.
  template<>
  struct container_traits_base<binomial_heap_tag>
  {
    typedef binomial_heap_tag 				container_category;
    typedef point_invalidation_guarantee 		invalidation_guarantee;

    enum
      {
	order_preserving = false,
	erase_can_throw = false,
	split_join_can_throw = false,
	reverse_iteration = false
      };
  };

  /// Specialization, rc binomial heap.
  template<>
  struct container_traits_base<rc_binomial_heap_tag>
  {
    typedef rc_binomial_heap_tag 			container_category;
    typedef point_invalidation_guarantee 		invalidation_guarantee;

    enum
      {
	order_preserving = false,
	erase_can_throw = false,
	split_join_can_throw = false,
	reverse_iteration = false
      };
  };

  /// Specialization, binary heap.
  template<>
  struct container_traits_base<binary_heap_tag>
  {
    typedef binary_heap_tag 				container_category;
    typedef basic_invalidation_guarantee 		invalidation_guarantee;

    enum
      {
	order_preserving = false,
	erase_can_throw = false,
	split_join_can_throw = true,
	reverse_iteration = false
      };
  };


  /// Container traits.
  // See Matt Austern for the name, S. Meyers MEFC++ #2, others.
  template<typename Cntnr>
  struct container_traits
  : public container_traits_base<typename Cntnr::container_category>
  {
    typedef Cntnr 				       container_type;
    typedef typename Cntnr::container_category         container_category;
    typedef container_traits_base<container_category>  base_type;
    typedef typename base_type::invalidation_guarantee invalidation_guarantee;

    enum
      {
	/// True only if Cntnr objects guarantee storing  keys by order.
	order_preserving = base_type::order_preserving,

	/// True only if erasing a key can throw.
	erase_can_throw = base_type::erase_can_throw,

	/// True only if split or join operations can throw.
	split_join_can_throw = base_type::split_join_can_throw,

	/// True only reverse iterators are supported.
	reverse_iteration = base_type::reverse_iteration
      };
  };
  //@}


  namespace detail
  {
    /// Dispatch mechanism, primary template for associative types.
    template<typename Key, typename Mapped, typename _Alloc, typename Tag,
	     typename Policy_Tl = null_type>
      struct container_base_dispatch;
  } // namespace detail
  //@}
} // namespace __gnu_pbds

#endif