Home | History | Annotate | Download | only in detail
      1 // -*- C++ -*-
      2 
      3 // Copyright (C) 2005, 2006, 2009, 2011 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 detail/types_traits.hpp
     38  * Contains a traits class of types used by containers.
     39  */
     40 
     41 #ifndef PB_DS_TYPES_TRAITS_HPP
     42 #define PB_DS_TYPES_TRAITS_HPP
     43 
     44 #include <algorithm>
     45 #include <utility>
     46 #include <ext/pb_ds/tag_and_trait.hpp>
     47 #include <ext/pb_ds/detail/type_utils.hpp>
     48 #include <utility>
     49 
     50 namespace __gnu_pbds
     51 {
     52   namespace detail
     53   {
     54     /**
     55      *  @addtogroup traits Traits
     56      *  @{
     57      */
     58 
     59     /// Primary template.
     60     template<typename Key, typename Mapped>
     61       struct no_throw_copies
     62       {
     63 	static const bool __simple = is_simple<Key>::value
     64 			   	 && is_simple<Mapped>::value;
     65 	typedef integral_constant<int, __simple> 	       	indicator;
     66       };
     67 
     68     /// Specialization.
     69     template<typename Key>
     70       struct no_throw_copies<Key, null_type>
     71       {
     72 	typedef integral_constant<int, is_simple<Key>::value> 	indicator;
     73       };
     74 
     75 
     76     /// Stored value.
     77     template<typename _Tv>
     78       struct stored_value
     79       {
     80 	typedef _Tv 	value_type;
     81 	value_type 	m_value;
     82       };
     83 
     84     /// Stored hash.
     85     template<typename _Th>
     86       struct stored_hash
     87       {
     88 	typedef _Th 	hash_type;
     89 	hash_type 	m_hash;
     90       };
     91 
     92     /// Primary template for representation of stored data.
     93     /// Two types of data can be stored: value and hash.
     94     template<typename _Tv, typename _Th>
     95       struct stored_data
     96       : public stored_value<_Tv>, public stored_hash<_Th>
     97       { };
     98 
     99     /// Specialization for representation of stored data of just value type.
    100     template<typename _Tv>
    101       struct stored_data<_Tv, null_type>
    102       : public stored_value<_Tv>
    103       { };
    104 
    105     /// Primary template.
    106     template<typename Key, typename Mapped, typename _Alloc, bool Store_Hash>
    107       struct type_base;
    108 
    109     /**
    110      * Specialization of type_base for the case where the hash value
    111      * is not stored alongside each value.
    112      */
    113     template<typename Key, typename Mapped, typename _Alloc>
    114       struct type_base<Key, Mapped, _Alloc, false>
    115       {
    116       public:
    117 	typedef typename _Alloc::size_type 		size_type;
    118 
    119       private:
    120 	typedef typename _Alloc::template rebind<Mapped>	__rebind_m;
    121 	typedef typename __rebind_m::other			__rebind_ma;
    122 	typedef std::pair<const Key, Mapped>			__value_type;
    123 	typedef typename _Alloc::template rebind<__value_type>	__rebind_v;
    124        	typedef typename __rebind_v::other			__rebind_va;
    125 
    126       public:
    127 	typedef typename __rebind_ma::value_type       	mapped_type;
    128 	typedef typename __rebind_ma::pointer 		mapped_pointer;
    129 	typedef typename __rebind_ma::const_pointer 	mapped_const_pointer;
    130 	typedef typename __rebind_ma::reference	       	mapped_reference;
    131 	typedef typename __rebind_ma::const_reference 	mapped_const_reference;
    132 
    133 	typedef typename __rebind_va::value_type 	value_type;
    134 	typedef typename __rebind_va::pointer 		pointer;
    135 	typedef typename __rebind_va::const_pointer 	const_pointer;
    136 	typedef typename __rebind_va::reference 	reference;
    137 	typedef typename __rebind_va::const_reference 	const_reference;
    138 
    139 	typedef stored_data<value_type, null_type>	stored_data_type;
    140       };
    141 
    142     /**
    143      * Specialization of type_base for the case where the hash value
    144      * is stored alongside each value.
    145      */
    146     template<typename Key, typename Mapped, typename _Alloc>
    147       struct type_base<Key, Mapped, _Alloc, true>
    148       {
    149       public:
    150 	typedef typename _Alloc::size_type 		size_type;
    151 
    152       private:
    153 	typedef typename _Alloc::template rebind<Mapped>	__rebind_m;
    154 	typedef typename __rebind_m::other			__rebind_ma;
    155 	typedef std::pair<const Key, Mapped>			__value_type;
    156 	typedef typename _Alloc::template rebind<__value_type>	__rebind_v;
    157        	typedef typename __rebind_v::other			__rebind_va;
    158 
    159       public:
    160 	typedef typename __rebind_ma::value_type       	mapped_type;
    161 	typedef typename __rebind_ma::pointer 		mapped_pointer;
    162 	typedef typename __rebind_ma::const_pointer 	mapped_const_pointer;
    163 	typedef typename __rebind_ma::reference	       	mapped_reference;
    164 	typedef typename __rebind_ma::const_reference 	mapped_const_reference;
    165 
    166 	typedef typename __rebind_va::value_type 	value_type;
    167 	typedef typename __rebind_va::pointer 		pointer;
    168 	typedef typename __rebind_va::const_pointer 	const_pointer;
    169 	typedef typename __rebind_va::reference 	reference;
    170 	typedef typename __rebind_va::const_reference 	const_reference;
    171 
    172 	typedef stored_data<value_type, size_type>	stored_data_type;
    173       };
    174 
    175 
    176     /**
    177      * Specialization of type_base for the case where the hash value
    178      * is not stored alongside each value.
    179      */
    180     template<typename Key, typename _Alloc>
    181       struct type_base<Key, null_type, _Alloc, false>
    182       {
    183       public:
    184 	typedef typename _Alloc::size_type 		size_type;
    185 	typedef Key 					value_type;
    186 
    187       private:
    188 	typedef typename _Alloc::template rebind<null_type>  	__rebind_m;
    189 	typedef typename __rebind_m::other			__rebind_ma;
    190 	typedef typename _Alloc::template rebind<value_type>	__rebind_v;
    191        	typedef typename __rebind_v::other			__rebind_va;
    192 
    193       public:
    194 	typedef typename __rebind_ma::value_type       	mapped_type;
    195 	typedef typename __rebind_ma::pointer 		mapped_pointer;
    196 	typedef typename __rebind_ma::const_pointer 	mapped_const_pointer;
    197 	typedef typename __rebind_ma::reference	       	mapped_reference;
    198 	typedef typename __rebind_ma::const_reference 	mapped_const_reference;
    199 
    200 	typedef typename __rebind_va::pointer 		pointer;
    201 	typedef typename __rebind_va::const_pointer 	const_pointer;
    202 	typedef typename __rebind_va::reference 	reference;
    203 	typedef typename __rebind_va::const_reference 	const_reference;
    204 
    205 	typedef stored_data<value_type, null_type>	stored_data_type;
    206 
    207 	static null_type 			s_null_type;
    208       };
    209 
    210     template<typename Key, typename _Alloc>
    211       null_type
    212       type_base<Key, null_type, _Alloc, false>::s_null_type;
    213 
    214 
    215     /**
    216      * Specialization of type_base for the case where the hash value
    217      * is stored alongside each value.
    218      */
    219     template<typename Key, typename _Alloc>
    220       struct type_base<Key, null_type, _Alloc, true>
    221       {
    222       public:
    223 	typedef typename _Alloc::size_type 		size_type;
    224 	typedef Key 					value_type;
    225 
    226       private:
    227 	typedef typename _Alloc::template rebind<null_type>  	__rebind_m;
    228 	typedef typename __rebind_m::other			__rebind_ma;
    229 	typedef typename _Alloc::template rebind<value_type>	__rebind_v;
    230        	typedef typename __rebind_v::other			__rebind_va;
    231 
    232       public:
    233 	typedef typename __rebind_ma::value_type       	mapped_type;
    234 	typedef typename __rebind_ma::pointer 		mapped_pointer;
    235 	typedef typename __rebind_ma::const_pointer 	mapped_const_pointer;
    236 	typedef typename __rebind_ma::reference	       	mapped_reference;
    237 	typedef typename __rebind_ma::const_reference 	mapped_const_reference;
    238 
    239 	typedef typename __rebind_va::pointer 		pointer;
    240 	typedef typename __rebind_va::const_pointer 	const_pointer;
    241 	typedef typename __rebind_va::reference 	reference;
    242 	typedef typename __rebind_va::const_reference 	const_reference;
    243 
    244 	typedef stored_data<value_type, size_type>	stored_data_type;
    245 
    246 	static null_type 		      	s_null_type;
    247       };
    248 
    249     template<typename Key, typename _Alloc>
    250       null_type
    251       type_base<Key, null_type, _Alloc, true>::s_null_type;
    252 
    253 
    254     /// Type base dispatch.
    255     template<typename Key, typename Mapped, typename _Alloc, bool Store_Hash>
    256       struct type_dispatch
    257       {
    258 	typedef type_base<Key, Mapped, _Alloc, Store_Hash> type;
    259       };
    260 
    261     /// Traits for abstract types.
    262     template<typename Key, typename Mapped, typename _Alloc, bool Store_Hash>
    263       struct types_traits
    264       : public type_dispatch<Key, Mapped, _Alloc, Store_Hash>::type
    265       {
    266       private:
    267 	typedef no_throw_copies<Key, Mapped>		__nothrowcopy;
    268 	typedef typename _Alloc::template rebind<Key>::other __rebind_a;
    269 
    270       public:
    271 	typedef typename _Alloc::size_type 		size_type;
    272 	typedef typename __rebind_a::value_type 	key_type;
    273 	typedef typename __rebind_a::pointer 		key_pointer;
    274 	typedef typename __rebind_a::const_pointer 	key_const_pointer;
    275 	typedef typename __rebind_a::reference 		key_reference;
    276 	typedef typename __rebind_a::const_reference 	key_const_reference;
    277 	typedef std::pair<size_type, size_type> 	comp_hash;
    278 	typedef integral_constant<int, Store_Hash> 	store_extra;
    279 	typedef typename __nothrowcopy::indicator 	no_throw_indicator;
    280 
    281 	store_extra			       	m_store_extra_indicator;
    282 	no_throw_indicator 		 	m_no_throw_copies_indicator;
    283     };
    284     //@}
    285   } // namespace detail
    286 } // namespace __gnu_pbds
    287 
    288 #endif
    289