Home | History | Annotate | Download | only in ov_tree_map_
      1 // -*- C++ -*-
      2 
      3 // Copyright (C) 2005, 2006, 2007, 2009 Free Software Foundation, Inc.
      4 //
      5 // This file is part of the GNU ISO C++ Library.  This library is free
      6 // software; you can redistribute it and/or modify it under the terms
      7 // of the GNU General Public License as published by the Free Software
      8 // Foundation; either version 3, or (at your option) any later
      9 // version.
     10 
     11 // This library is distributed in the hope that it will be useful, but
     12 // WITHOUT ANY WARRANTY; without even the implied warranty of
     13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14 // General Public License for more details.
     15 
     16 // Under Section 7 of GPL version 3, you are granted additional
     17 // permissions described in the GCC Runtime Library Exception, version
     18 // 3.1, as published by the Free Software Foundation.
     19 
     20 // You should have received a copy of the GNU General Public License and
     21 // a copy of the GCC Runtime Library Exception along with this program;
     22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     23 // <http://www.gnu.org/licenses/>.
     24 
     25 // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.
     26 
     27 // Permission to use, copy, modify, sell, and distribute this software
     28 // is hereby granted without fee, provided that the above copyright
     29 // notice appears in all copies, and that both that copyright notice
     30 // and this permission notice appear in supporting documentation. None
     31 // of the above authors, nor IBM Haifa Research Laboratories, make any
     32 // representation about the suitability of this software for any
     33 // purpose. It is provided "as is" without express or implied
     34 // warranty.
     35 
     36 /**
     37  * @file node_iterators.hpp
     38  * Contains an implementation class for ov_tree_.
     39  */
     40 
     41 #ifndef PB_DS_OV_TREE_NODE_ITERATORS_HPP
     42 #define PB_DS_OV_TREE_NODE_ITERATORS_HPP
     43 
     44 #include <ext/pb_ds/tag_and_trait.hpp>
     45 #include <ext/pb_ds/detail/type_utils.hpp>
     46 #include <debug/debug.h>
     47 
     48 namespace __gnu_pbds
     49 {
     50   namespace detail
     51   {
     52 
     53 #define PB_DS_OV_TREE_CONST_NODE_ITERATOR_C_DEC	\
     54     ov_tree_node_const_it_<Value_Type, Metadata_Type, Allocator>
     55 
     56     // Const node reference.
     57     template<typename Value_Type, typename Metadata_Type, class Allocator>
     58     class ov_tree_node_const_it_
     59     {
     60 
     61     protected:
     62       typedef
     63       typename Allocator::template rebind<
     64       Value_Type>::other::pointer
     65       pointer;
     66 
     67       typedef
     68       typename Allocator::template rebind<
     69 	Value_Type>::other::const_pointer
     70       const_pointer;
     71 
     72       typedef
     73       typename Allocator::template rebind<
     74 	Metadata_Type>::other::const_pointer
     75       const_metadata_pointer;
     76 
     77       typedef PB_DS_OV_TREE_CONST_NODE_ITERATOR_C_DEC this_type;
     78 
     79     protected:
     80 
     81       template<typename Ptr>
     82       inline static Ptr
     83       mid_pointer(Ptr p_begin, Ptr p_end)
     84       {
     85 	_GLIBCXX_DEBUG_ASSERT(p_end >= p_begin);
     86 	return (p_begin + (p_end - p_begin) / 2);
     87       }
     88 
     89     public:
     90 
     91       typedef trivial_iterator_tag iterator_category;
     92 
     93       typedef trivial_iterator_difference_type difference_type;
     94 
     95       typedef
     96       typename Allocator::template rebind<
     97 	Value_Type>::other::const_pointer
     98       value_type;
     99 
    100       typedef
    101       typename Allocator::template rebind<
    102 	typename remove_const<
    103 	Value_Type>::type>::other::const_pointer
    104       reference;
    105 
    106       typedef
    107       typename Allocator::template rebind<
    108 	typename remove_const<
    109 	Value_Type>::type>::other::const_pointer
    110       const_reference;
    111 
    112       typedef Metadata_Type metadata_type;
    113 
    114       typedef
    115       typename Allocator::template rebind<
    116 	metadata_type>::other::const_reference
    117       const_metadata_reference;
    118 
    119     public:
    120       inline
    121       ov_tree_node_const_it_(const_pointer p_nd = NULL,  const_pointer p_begin_nd = NULL,  const_pointer p_end_nd = NULL,  const_metadata_pointer p_metadata = NULL) : m_p_value(const_cast<pointer>(p_nd)), m_p_begin_value(const_cast<pointer>(p_begin_nd)), m_p_end_value(const_cast<pointer>(p_end_nd)), m_p_metadata(p_metadata)
    122       { }
    123 
    124       inline const_reference
    125       operator*() const
    126       { return m_p_value; }
    127 
    128       inline const_metadata_reference
    129       get_metadata() const
    130       {
    131 	enum
    132 	  {
    133 	    has_metadata = !is_same<Metadata_Type, null_node_metadata>::value
    134 	  };
    135 
    136 	PB_DS_STATIC_ASSERT(should_have_metadata, has_metadata);
    137 	_GLIBCXX_DEBUG_ASSERT(m_p_metadata != NULL);
    138 	return *m_p_metadata;
    139       }
    140 
    141       inline this_type
    142       get_l_child() const
    143       {
    144 	if (m_p_begin_value == m_p_value)
    145 	  return (this_type(m_p_begin_value, m_p_begin_value, m_p_begin_value));
    146 
    147 	const_metadata_pointer p_begin_metadata =
    148 	  m_p_metadata - (m_p_value - m_p_begin_value);
    149 
    150 	return (this_type(mid_pointer(m_p_begin_value, m_p_value),
    151 			  m_p_begin_value,
    152 			  m_p_value,
    153 			  mid_pointer(p_begin_metadata, m_p_metadata)));
    154       }
    155 
    156       inline this_type
    157       get_r_child() const
    158       {
    159 	if (m_p_value == m_p_end_value)
    160 	  return (this_type(m_p_end_value,  m_p_end_value,  m_p_end_value));
    161 
    162 	const_metadata_pointer p_end_metadata =
    163 	  m_p_metadata + (m_p_end_value - m_p_value);
    164 
    165 	return (this_type(mid_pointer(m_p_value + 1, m_p_end_value),
    166 			  m_p_value + 1,
    167 			  m_p_end_value,(m_p_metadata == NULL) ?
    168 			  NULL : mid_pointer(m_p_metadata + 1, p_end_metadata)));
    169       }
    170 
    171       inline bool
    172       operator==(const this_type& other) const
    173       {
    174 	const bool is_end = m_p_begin_value == m_p_end_value;
    175 	const bool is_other_end = other.m_p_begin_value == other.m_p_end_value;
    176 
    177 	if (is_end)
    178 	  return (is_other_end);
    179 
    180 	if (is_other_end)
    181 	  return (is_end);
    182 
    183 	return m_p_value == other.m_p_value;
    184       }
    185 
    186       inline bool
    187       operator!=(const this_type& other) const
    188       { return !operator==(other); }
    189 
    190     public:
    191       pointer m_p_value;
    192       pointer m_p_begin_value;
    193       pointer m_p_end_value;
    194 
    195       const_metadata_pointer m_p_metadata;
    196     };
    197 
    198 #define PB_DS_OV_TREE_NODE_ITERATOR_C_DEC \
    199     ov_tree_node_it_<Value_Type, Metadata_Type, Allocator>
    200 
    201     // Node reference.
    202     template<typename Value_Type, typename Metadata_Type, class Allocator>
    203     class ov_tree_node_it_ : public PB_DS_OV_TREE_CONST_NODE_ITERATOR_C_DEC
    204     {
    205 
    206     private:
    207       typedef PB_DS_OV_TREE_NODE_ITERATOR_C_DEC this_type;
    208 
    209       typedef PB_DS_OV_TREE_CONST_NODE_ITERATOR_C_DEC base_type;
    210 
    211       typedef typename base_type::pointer pointer;
    212 
    213       typedef typename base_type::const_pointer const_pointer;
    214 
    215       typedef
    216       typename base_type::const_metadata_pointer
    217       const_metadata_pointer;
    218 
    219     public:
    220 
    221       typedef trivial_iterator_tag iterator_category;
    222 
    223       typedef trivial_iterator_difference_type difference_type;
    224 
    225       typedef
    226       typename Allocator::template rebind<
    227 	Value_Type>::other::pointer
    228       value_type;
    229 
    230       typedef
    231       typename Allocator::template rebind<
    232 	typename remove_const<
    233 	Value_Type>::type>::other::pointer
    234       reference;
    235 
    236       typedef
    237       typename Allocator::template rebind<
    238 	typename remove_const<
    239 	Value_Type>::type>::other::pointer
    240       const_reference;
    241 
    242     public:
    243       inline
    244       ov_tree_node_it_(const_pointer p_nd = NULL,  const_pointer p_begin_nd = NULL,  const_pointer p_end_nd = NULL,  const_metadata_pointer p_metadata = NULL) : base_type(p_nd,  p_begin_nd,  p_end_nd,  p_metadata)
    245       { }
    246 
    247       // Access.
    248       inline reference
    249       operator*() const
    250       { return reference(base_type::m_p_value); }
    251 
    252       // Returns the node reference associated with the left node.
    253       inline ov_tree_node_it_
    254       get_l_child() const
    255       {
    256 	if (base_type::m_p_begin_value == base_type::m_p_value)
    257 	  return (this_type(base_type::m_p_begin_value,  base_type::m_p_begin_value,  base_type::m_p_begin_value));
    258 
    259 	const_metadata_pointer p_begin_metadata =
    260 	  base_type::m_p_metadata - (base_type::m_p_value - base_type::m_p_begin_value);
    261 
    262 	return (this_type(base_type::mid_pointer(base_type::m_p_begin_value, base_type::m_p_value),
    263 			  base_type::m_p_begin_value,
    264 			  base_type::m_p_value,
    265 			  base_type::mid_pointer(p_begin_metadata, base_type::m_p_metadata)));
    266       }
    267 
    268       // Returns the node reference associated with the right node.
    269       inline ov_tree_node_it_
    270       get_r_child() const
    271       {
    272 	if (base_type::m_p_value == base_type::m_p_end_value)
    273 	  return (this_type(base_type::m_p_end_value,  base_type::m_p_end_value,  base_type::m_p_end_value));
    274 
    275 	const_metadata_pointer p_end_metadata =
    276 	  base_type::m_p_metadata + (base_type::m_p_end_value - base_type::m_p_value);
    277 
    278 	return (this_type(base_type::mid_pointer(base_type::m_p_value + 1, base_type::m_p_end_value),
    279 			  base_type::m_p_value + 1,
    280 			  base_type::m_p_end_value,(base_type::m_p_metadata == NULL)?
    281 			  NULL : base_type::mid_pointer(base_type::m_p_metadata + 1, p_end_metadata)));
    282       }
    283 
    284     };
    285 
    286 #undef PB_DS_OV_TREE_NODE_ITERATOR_C_DEC
    287 #undef PB_DS_OV_TREE_CONST_NODE_ITERATOR_C_DEC
    288 
    289 } // namespace detail
    290 } // namespace __gnu_pbds
    291 
    292 #endif
    293