1169691Skan// -*- C++ -*-
2169691Skan
3169691Skan// Copyright (C) 2005, 2006 Free Software Foundation, Inc.
4169691Skan//
5169691Skan// This file is part of the GNU ISO C++ Library.  This library is free
6169691Skan// software; you can redistribute it and/or modify it under the terms
7169691Skan// of the GNU General Public License as published by the Free Software
8169691Skan// Foundation; either version 2, or (at your option) any later
9169691Skan// version.
10169691Skan
11169691Skan// This library is distributed in the hope that it will be useful, but
12169691Skan// WITHOUT ANY WARRANTY; without even the implied warranty of
13169691Skan// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14169691Skan// General Public License for more details.
15169691Skan
16169691Skan// You should have received a copy of the GNU General Public License
17169691Skan// along with this library; see the file COPYING.  If not, write to
18169691Skan// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
19169691Skan// MA 02111-1307, USA.
20169691Skan
21169691Skan// As a special exception, you may use this file as part of a free
22169691Skan// software library without restriction.  Specifically, if other files
23169691Skan// instantiate templates or use macros or inline functions from this
24169691Skan// file, or you compile this file and link it with other files to
25169691Skan// produce an executable, this file does not by itself cause the
26169691Skan// resulting executable to be covered by the GNU General Public
27169691Skan// License.  This exception does not however invalidate any other
28169691Skan// reasons why the executable file might be covered by the GNU General
29169691Skan// Public License.
30169691Skan
31169691Skan// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.
32169691Skan
33169691Skan// Permission to use, copy, modify, sell, and distribute this software
34169691Skan// is hereby granted without fee, provided that the above copyright
35169691Skan// notice appears in all copies, and that both that copyright notice
36169691Skan// and this permission notice appear in supporting documentation. None
37169691Skan// of the above authors, nor IBM Haifa Research Laboratories, make any
38169691Skan// representation about the suitability of this software for any
39169691Skan// purpose. It is provided "as is" without express or implied
40169691Skan// warranty.
41169691Skan
42169691Skan/**
43169691Skan * @file tag_and_trait.hpp
44169691Skan * Contains tags and traits, e.g., ones describing underlying
45169691Skan *    data structures.
46169691Skan */
47169691Skan
48169691Skan#ifndef PB_DS_TAG_AND_TRAIT_HPP
49169691Skan#define PB_DS_TAG_AND_TRAIT_HPP
50169691Skan
51169691Skan#include <ext/pb_ds/detail/type_utils.hpp>
52169691Skan
53169691Skannamespace pb_ds
54169691Skan{
55169691Skan  // A trivial iterator tag. Signifies that the iterators has none of
56169691Skan  // the STL's movement abilities.
57169691Skan  struct trivial_iterator_tag
58169691Skan  { };
59169691Skan
60169691Skan  // Prohibit moving trivial iterators.
61169691Skan  typedef void trivial_iterator_difference_type;
62169691Skan
63169691Skan
64169691Skan  // Signifies a basic invalidation guarantee that any iterator,
65169691Skan  // pointer, or reference to a container object's mapped value type
66169691Skan  // is valid as long as the container is not modified.
67169691Skan  struct basic_invalidation_guarantee
68169691Skan  { };
69169691Skan
70169691Skan  // Signifies an invalidation guarantee that includes all those of
71169691Skan  // its base, and additionally, that any point-type iterator,
72169691Skan  // pointer, or reference to a container object's mapped value type
73169691Skan  // is valid as long as its corresponding entry has not be erased,
74169691Skan  // regardless of modifications to the container object.
75169691Skan  struct point_invalidation_guarantee : public basic_invalidation_guarantee
76169691Skan  { };
77169691Skan
78169691Skan  // Signifies an invalidation guarantee that includes all those of
79169691Skan  // its base, and additionally, that any range-type iterator
80169691Skan  // (including the returns of begin() and end()) is in the correct
81169691Skan  // relative positions to other range-type iterators as long as its
82169691Skan  // corresponding entry has not be erased, regardless of
83169691Skan  // modifications to the container object.
84169691Skan  struct range_invalidation_guarantee : public point_invalidation_guarantee
85169691Skan  { };
86169691Skan
87169691Skan
88169691Skan  // A mapped-policy indicating that an associative container is a set.
89169691Skan  // XXX should this be a trait of the form is_set<T> ??
90169691Skan  struct null_mapped_type { };
91169691Skan
92169691Skan
93169691Skan  // Base data structure tag.
94169691Skan  struct container_tag
95169691Skan  { };
96169691Skan
97169691Skan  // Basic associative-container.
98169691Skan  struct associative_container_tag : public container_tag { };
99169691Skan
100169691Skan  // Basic hash.
101169691Skan  struct basic_hash_tag : public associative_container_tag { };
102169691Skan
103169691Skan  // Collision-chaining hash.
104169691Skan  struct cc_hash_tag : public basic_hash_tag { };
105169691Skan
106169691Skan  // General-probing hash.
107169691Skan  struct gp_hash_tag : public basic_hash_tag { };
108169691Skan
109169691Skan  // Basic tree.
110169691Skan  struct basic_tree_tag : public associative_container_tag { };
111169691Skan
112169691Skan  // tree.
113169691Skan  struct tree_tag : public basic_tree_tag { };
114169691Skan
115169691Skan  // Red-black tree.
116169691Skan  struct rb_tree_tag : public tree_tag { };
117169691Skan
118169691Skan  // Splay tree.
119169691Skan  struct splay_tree_tag : public tree_tag { };
120169691Skan
121169691Skan  // Ordered-vector tree.
122169691Skan  struct ov_tree_tag : public tree_tag { };
123169691Skan
124169691Skan  // trie.
125169691Skan  struct trie_tag : public basic_tree_tag { };
126169691Skan
127169691Skan  // PATRICIA trie.
128169691Skan  struct pat_trie_tag : public trie_tag { };
129169691Skan
130169691Skan  // List-update.
131169691Skan  struct list_update_tag : public associative_container_tag { };
132169691Skan
133169691Skan  // Basic priority-queue.
134169691Skan  struct priority_queue_tag : public container_tag { };
135169691Skan
136169691Skan  // Pairing-heap.
137169691Skan  struct pairing_heap_tag : public priority_queue_tag { };
138169691Skan
139169691Skan  // Binomial-heap.
140169691Skan  struct binomial_heap_tag : public priority_queue_tag { };
141169691Skan
142169691Skan  // Redundant-counter binomial-heap.
143169691Skan  struct rc_binomial_heap_tag : public priority_queue_tag { };
144169691Skan
145169691Skan  // Binary-heap (array-based).
146169691Skan  struct binary_heap_tag : public priority_queue_tag { };
147169691Skan
148169691Skan  // Thin heap.
149169691Skan  struct thin_heap_tag : public priority_queue_tag { };
150169691Skan
151169691Skan
152169691Skan  template<typename Tag>
153169691Skan  struct container_traits_base;
154169691Skan
155169691Skan  template<>
156169691Skan  struct container_traits_base<cc_hash_tag>
157169691Skan  {
158169691Skan    typedef cc_hash_tag container_category;
159169691Skan    typedef point_invalidation_guarantee invalidation_guarantee;
160169691Skan
161169691Skan    enum
162169691Skan      {
163169691Skan        order_preserving = false,
164169691Skan        erase_can_throw = false,
165169691Skan	split_join_can_throw = false,
166169691Skan	reverse_iteration = false
167169691Skan      };
168169691Skan  };
169169691Skan
170169691Skan  template<>
171169691Skan  struct container_traits_base<gp_hash_tag>
172169691Skan  {
173169691Skan    typedef gp_hash_tag container_category;
174169691Skan    typedef basic_invalidation_guarantee invalidation_guarantee;
175169691Skan
176169691Skan    enum
177169691Skan      {
178169691Skan        order_preserving = false,
179169691Skan	erase_can_throw = false,
180169691Skan	split_join_can_throw = false,
181169691Skan	reverse_iteration = false
182169691Skan      };
183169691Skan  };
184169691Skan
185169691Skan  template<>
186169691Skan  struct container_traits_base<rb_tree_tag>
187169691Skan  {
188169691Skan    typedef rb_tree_tag container_category;
189169691Skan    typedef range_invalidation_guarantee invalidation_guarantee;
190169691Skan
191169691Skan    enum
192169691Skan      {
193169691Skan        order_preserving = true,
194169691Skan        erase_can_throw = false,
195169691Skan	split_join_can_throw = false,
196169691Skan        reverse_iteration = true
197169691Skan      };
198169691Skan  };
199169691Skan
200169691Skan  template<>
201169691Skan  struct container_traits_base<splay_tree_tag>
202169691Skan  {
203169691Skan    typedef splay_tree_tag container_category;
204169691Skan    typedef range_invalidation_guarantee invalidation_guarantee;
205169691Skan
206169691Skan    enum
207169691Skan      {
208169691Skan        order_preserving = true,
209169691Skan        erase_can_throw = false,
210169691Skan        split_join_can_throw = false,
211169691Skan        reverse_iteration = true
212169691Skan      };
213169691Skan  };
214169691Skan
215169691Skan  template<>
216169691Skan  struct container_traits_base<ov_tree_tag>
217169691Skan  {
218169691Skan    typedef ov_tree_tag container_category;
219169691Skan    typedef basic_invalidation_guarantee invalidation_guarantee;
220169691Skan
221169691Skan    enum
222169691Skan      {
223169691Skan        order_preserving = true,
224169691Skan        erase_can_throw = true,
225169691Skan        split_join_can_throw = true,
226169691Skan        reverse_iteration = false
227169691Skan      };
228169691Skan  };
229169691Skan
230169691Skan  template<>
231169691Skan  struct container_traits_base<pat_trie_tag>
232169691Skan  {
233169691Skan    typedef pat_trie_tag container_category;
234169691Skan    typedef range_invalidation_guarantee invalidation_guarantee;
235169691Skan
236169691Skan    enum
237169691Skan      {
238169691Skan        order_preserving = true,
239169691Skan        erase_can_throw = false,
240169691Skan        split_join_can_throw = true,
241169691Skan        reverse_iteration = true
242169691Skan      };
243169691Skan  };
244169691Skan
245169691Skan  template<>
246169691Skan  struct container_traits_base<list_update_tag>
247169691Skan  {
248169691Skan    typedef list_update_tag container_category;
249169691Skan    typedef point_invalidation_guarantee invalidation_guarantee;
250169691Skan
251169691Skan    enum
252169691Skan      {
253169691Skan        order_preserving = false,
254169691Skan        erase_can_throw = false,
255169691Skan	split_join_can_throw = false,
256169691Skan        reverse_iteration = false
257169691Skan      };
258169691Skan  };
259169691Skan
260169691Skan
261169691Skan  template<>
262169691Skan  struct container_traits_base<pairing_heap_tag>
263169691Skan  {
264169691Skan    typedef pairing_heap_tag container_category;
265169691Skan    typedef point_invalidation_guarantee invalidation_guarantee;
266169691Skan
267169691Skan    enum
268169691Skan      {
269169691Skan        order_preserving = false,
270169691Skan        erase_can_throw = false,
271169691Skan	split_join_can_throw = false,
272169691Skan        reverse_iteration = false
273169691Skan      };
274169691Skan  };
275169691Skan
276169691Skan  template<>
277169691Skan  struct container_traits_base<thin_heap_tag>
278169691Skan  {
279169691Skan    typedef thin_heap_tag container_category;
280169691Skan    typedef point_invalidation_guarantee invalidation_guarantee;
281169691Skan
282169691Skan    enum
283169691Skan      {
284169691Skan        order_preserving = false,
285169691Skan        erase_can_throw = false,
286169691Skan	split_join_can_throw = false,
287169691Skan        reverse_iteration = false
288169691Skan      };
289169691Skan  };
290169691Skan
291169691Skan  template<>
292169691Skan  struct container_traits_base<binomial_heap_tag>
293169691Skan  {
294169691Skan    typedef binomial_heap_tag container_category;
295169691Skan    typedef point_invalidation_guarantee invalidation_guarantee;
296169691Skan
297169691Skan    enum
298169691Skan      {
299169691Skan        order_preserving = false,
300169691Skan        erase_can_throw = false,
301169691Skan	split_join_can_throw = false,
302169691Skan        reverse_iteration = false
303169691Skan      };
304169691Skan  };
305169691Skan
306169691Skan  template<>
307169691Skan  struct container_traits_base<rc_binomial_heap_tag>
308169691Skan  {
309169691Skan    typedef rc_binomial_heap_tag container_category;
310169691Skan    typedef point_invalidation_guarantee invalidation_guarantee;
311169691Skan
312169691Skan    enum
313169691Skan      {
314169691Skan        order_preserving = false,
315169691Skan        erase_can_throw = false,
316169691Skan	split_join_can_throw = false,
317169691Skan        reverse_iteration = false
318169691Skan      };
319169691Skan  };
320169691Skan
321169691Skan  template<>
322169691Skan  struct container_traits_base<binary_heap_tag>
323169691Skan  {
324169691Skan    typedef binary_heap_tag container_category;
325169691Skan    typedef basic_invalidation_guarantee invalidation_guarantee;
326169691Skan
327169691Skan    enum
328169691Skan      {
329169691Skan        order_preserving = false,
330169691Skan        erase_can_throw = false,
331169691Skan	split_join_can_throw = true,
332169691Skan        reverse_iteration = false
333169691Skan      };
334169691Skan  };
335169691Skan
336169691Skan
337169691Skan  // See Matt Austern for the name, S. Meyers MEFC++ #2, others.
338169691Skan  template<typename Cntnr>
339169691Skan  struct container_traits
340169691Skan  : public container_traits_base<typename Cntnr::container_category>
341169691Skan  {
342169691Skan    typedef Cntnr container_type;
343169691Skan    typedef typename Cntnr::container_category container_category;
344169691Skan    typedef container_traits_base<container_category> base_type;
345169691Skan    typedef typename base_type::invalidation_guarantee invalidation_guarantee;
346169691Skan
347169691Skan    enum
348169691Skan      {
349169691Skan	order_preserving = base_type::order_preserving,
350169691Skan	erase_can_throw = base_type::erase_can_throw,
351169691Skan	split_join_can_throw = base_type::split_join_can_throw,
352169691Skan	reverse_iteration = base_type::reverse_iteration
353169691Skan      };
354169691Skan  };
355169691Skan} // namespace pb_ds
356169691Skan
357169691Skan#endif
358