|
| 1 | +// -*- mode:c++ -*- |
| 2 | +// |
| 3 | +// Header file algorithms.hpp |
| 4 | +// |
| 5 | +// Uniform interface layer for all containers. |
| 6 | +// |
| 7 | +// Copyright (c) 2003 Raoul M. Gough |
| 8 | +// |
| 9 | +// This material is provided "as is", with absolutely no warranty expressed |
| 10 | +// or implied. Any use is at your own risk. |
| 11 | +// |
| 12 | +// Permission to use or copy this material for any purpose is hereby |
| 13 | +// granted without fee, provided the above notices are retained on all |
| 14 | +// copies. Permission to modify the material and to distribute modified |
| 15 | +// versions is granted, provided the above notices are retained, and a |
| 16 | +// notice that the material was modified is included with the above |
| 17 | +// copyright notice. |
| 18 | +// |
| 19 | +// History |
| 20 | +// ======= |
| 21 | +// 2003/ 9/11 rmg File creation from suite_utils.hpp |
| 22 | +// |
| 23 | +// $Id$ |
| 24 | +// |
| 25 | + |
| 26 | +#ifndef algorithms_rmg_20030823_included |
| 27 | +#define algorithms_rmg_20030823_included |
| 28 | + |
| 29 | +#include "suite_utils.hpp" |
| 30 | +#include <boost/type_traits.hpp> |
| 31 | +#include <boost/call_traits.hpp> |
| 32 | +#include <algorithm> |
| 33 | +#include <stdexcept> |
| 34 | +#include <string> |
| 35 | + |
| 36 | +namespace indexing { |
| 37 | + template<typename ContainerTraits> |
| 38 | + struct default_algorithms |
| 39 | + { |
| 40 | + typedef ContainerTraits container_traits; |
| 41 | + |
| 42 | + typedef typename ContainerTraits::container container; |
| 43 | + typedef typename ContainerTraits::iterator iterator; |
| 44 | + typedef typename ContainerTraits::reference reference; |
| 45 | + typedef typename ContainerTraits::key_type key_type; |
| 46 | + typedef typename ContainerTraits::size_type size_type; |
| 47 | + typedef typename ContainerTraits::index_type index_type; |
| 48 | + typedef typename ContainerTraits::value_type value_type; |
| 49 | + |
| 50 | + typedef typename boost::call_traits<value_type>::param_type value_param; |
| 51 | + typedef typename boost::call_traits<key_type>::param_type key_param; |
| 52 | + typedef typename boost::call_traits<index_type>::param_type index_param; |
| 53 | + |
| 54 | + static size_type size (container &); |
| 55 | + static iterator find (container &, key_param); |
| 56 | + static size_type count (container &, key_param); |
| 57 | + static void reverse (container &); |
| 58 | + static reference get (container &, index_param); |
| 59 | + static void assign (container &, index_param, value_param); |
| 60 | + static void insert (container &, index_param, value_param); |
| 61 | + static void erase (container &, index_param, index_param); |
| 62 | + static void push_back (container &, value_param); |
| 63 | + static void sort (container &); |
| 64 | + // static void sort (container &, PyObject *); |
| 65 | + |
| 66 | + static iterator begin (container &c) { return c.begin(); } |
| 67 | + static iterator end (container &c) { return c.end(); } |
| 68 | + }; |
| 69 | + |
| 70 | + ///////////////////////////////////////////////////////////////////////// |
| 71 | + // Get the size of a container |
| 72 | + ///////////////////////////////////////////////////////////////////////// |
| 73 | + |
| 74 | + template<typename ContainerTraits> |
| 75 | + typename default_algorithms<ContainerTraits>::size_type |
| 76 | + default_algorithms<ContainerTraits>::size (container &c) |
| 77 | + { |
| 78 | + return c.size(); |
| 79 | + } |
| 80 | + |
| 81 | + ///////////////////////////////////////////////////////////////////////// |
| 82 | + // Find an element in a container (std algorithm version) |
| 83 | + ///////////////////////////////////////////////////////////////////////// |
| 84 | + |
| 85 | + template<typename ContainerTraits> |
| 86 | + typename default_algorithms<ContainerTraits>::iterator |
| 87 | + default_algorithms<ContainerTraits>::find (container &c |
| 88 | + , key_param key) |
| 89 | + { |
| 90 | + return std::find (begin(c), end(c), key); |
| 91 | + } |
| 92 | + |
| 93 | + ///////////////////////////////////////////////////////////////////////// |
| 94 | + // Count occurances of an element in a container (std algorithm version) |
| 95 | + ///////////////////////////////////////////////////////////////////////// |
| 96 | + |
| 97 | + template<typename ContainerTraits> |
| 98 | + typename default_algorithms<ContainerTraits>::size_type |
| 99 | + default_algorithms<ContainerTraits>::count (container &c |
| 100 | + , key_param key) |
| 101 | + { |
| 102 | + return std::count (begin(c), end(c), key); |
| 103 | + } |
| 104 | + |
| 105 | + ///////////////////////////////////////////////////////////////////////// |
| 106 | + // Index into a container (generic version) |
| 107 | + ///////////////////////////////////////////////////////////////////////// |
| 108 | + |
| 109 | + template<typename ContainerTraits> |
| 110 | + typename default_algorithms<ContainerTraits>::reference |
| 111 | + default_algorithms<ContainerTraits>::get (container &c, index_param ix) |
| 112 | + { |
| 113 | + return c.at (ix); |
| 114 | + } |
| 115 | + |
| 116 | + ///////////////////////////////////////////////////////////////////////// |
| 117 | + // Assign a value at a particular index (generic version) |
| 118 | + ///////////////////////////////////////////////////////////////////////// |
| 119 | + |
| 120 | + template<typename ContainerTraits> |
| 121 | + void |
| 122 | + default_algorithms<ContainerTraits>::assign (container &c |
| 123 | + , index_param ix |
| 124 | + , value_param val) |
| 125 | + { |
| 126 | + c.at(ix) = val; |
| 127 | + } |
| 128 | + |
| 129 | + ///////////////////////////////////////////////////////////////////////// |
| 130 | + // Insert at end of a container (generic version) |
| 131 | + ///////////////////////////////////////////////////////////////////////// |
| 132 | + |
| 133 | + template<typename ContainerTraits> |
| 134 | + void |
| 135 | + default_algorithms<ContainerTraits>::push_back (container &c |
| 136 | + , value_param v) |
| 137 | + { |
| 138 | + c.push_back (v); |
| 139 | + } |
| 140 | + |
| 141 | + ///////////////////////////////////////////////////////////////////////// |
| 142 | + // Insert at an index in the container (generic version) |
| 143 | + ///////////////////////////////////////////////////////////////////////// |
| 144 | + |
| 145 | + template<typename ContainerTraits> |
| 146 | + void |
| 147 | + default_algorithms<ContainerTraits>::insert (container &c |
| 148 | + , index_param i |
| 149 | + , value_param v) |
| 150 | + { |
| 151 | + c.insert (c.begin() + i, v); |
| 152 | + } |
| 153 | + |
| 154 | + ///////////////////////////////////////////////////////////////////////// |
| 155 | + // Erase between given indexes in the container (generic version) |
| 156 | + ///////////////////////////////////////////////////////////////////////// |
| 157 | + |
| 158 | + template<typename ContainerTraits> |
| 159 | + void |
| 160 | + default_algorithms<ContainerTraits>::erase (container &c |
| 161 | + , index_param from |
| 162 | + , index_param to) |
| 163 | + { |
| 164 | + c.erase (c.begin() + from, c.begin() + to); |
| 165 | + } |
| 166 | + |
| 167 | + ///////////////////////////////////////////////////////////////////////// |
| 168 | + // Reverse the contents of a container (std algorithm version) |
| 169 | + ///////////////////////////////////////////////////////////////////////// |
| 170 | + |
| 171 | + template<typename ContainerTraits> |
| 172 | + void default_algorithms<ContainerTraits>::reverse (container &c) |
| 173 | + { |
| 174 | + std::reverse (begin(c), end(c)); |
| 175 | + } |
| 176 | + |
| 177 | + ///////////////////////////////////////////////////////////////////////// |
| 178 | + // Sort the contents of a container (std algorithm version) |
| 179 | + ///////////////////////////////////////////////////////////////////////// |
| 180 | + |
| 181 | + template<typename ContainerTraits> |
| 182 | + void default_algorithms<ContainerTraits>::sort (container &c) |
| 183 | + { |
| 184 | + std::sort (begin(c), end(c)); |
| 185 | + } |
| 186 | + |
| 187 | + ///////////////////////////////////////////////////////////////////////// |
| 188 | + // Special cases for std::list |
| 189 | + ///////////////////////////////////////////////////////////////////////// |
| 190 | + |
| 191 | + template<typename ContainerTraits> |
| 192 | + struct list_algorithms : public default_algorithms<ContainerTraits> |
| 193 | + { |
| 194 | + private: |
| 195 | + typedef default_algorithms<ContainerTraits> Parent; |
| 196 | + |
| 197 | + public: |
| 198 | + typedef typename Parent::container container; |
| 199 | + |
| 200 | + // Use member functions for the following (hiding base class versions) |
| 201 | + static void reverse (container &); |
| 202 | + static void sort (container &); |
| 203 | + // static void sort (container &, PyObject *); |
| 204 | + }; |
| 205 | + |
| 206 | + ///////////////////////////////////////////////////////////////////////// |
| 207 | + // Reverse the contents of a list (member function version) |
| 208 | + ///////////////////////////////////////////////////////////////////////// |
| 209 | + |
| 210 | + template<typename ContainerTraits> |
| 211 | + void list_algorithms<ContainerTraits>::reverse (container &c) |
| 212 | + { |
| 213 | + c.reverse(); |
| 214 | + } |
| 215 | + |
| 216 | + ///////////////////////////////////////////////////////////////////////// |
| 217 | + // Sort the contents of a container (std algorithm version) |
| 218 | + ///////////////////////////////////////////////////////////////////////// |
| 219 | + |
| 220 | + template<typename ContainerTraits> |
| 221 | + void list_algorithms<ContainerTraits>::sort (container &c) |
| 222 | + { |
| 223 | + c.sort(); |
| 224 | + } |
| 225 | + |
| 226 | + ///////////////////////////////////////////////////////////////////////// |
| 227 | + // Special cases for associative containers |
| 228 | + ///////////////////////////////////////////////////////////////////////// |
| 229 | + |
| 230 | + template<typename ContainerTraits> |
| 231 | + struct assoc_algorithms : public default_algorithms<ContainerTraits> |
| 232 | + { |
| 233 | + private: |
| 234 | + typedef default_algorithms<ContainerTraits> Parent; |
| 235 | + |
| 236 | + public: |
| 237 | + typedef typename Parent::iterator iterator; |
| 238 | + typedef typename Parent::size_type size_type; |
| 239 | + typedef typename Parent::container container; |
| 240 | + typedef typename Parent::reference reference; |
| 241 | + typedef typename Parent::key_param key_param; |
| 242 | + typedef typename Parent::index_param index_param; |
| 243 | + typedef typename Parent::value_param value_param; |
| 244 | + |
| 245 | + static reference get (container &, index_param); |
| 246 | + static void assign (container &, index_param, value_param); |
| 247 | + |
| 248 | + // Use member functions for the following (hiding base class versions) |
| 249 | + static iterator find (container &, key_param); |
| 250 | + static size_type count (container &, key_param); |
| 251 | + }; |
| 252 | + |
| 253 | + ///////////////////////////////////////////////////////////////////////// |
| 254 | + // Index into a container (associative version) |
| 255 | + ///////////////////////////////////////////////////////////////////////// |
| 256 | + |
| 257 | + template<typename ContainerTraits> |
| 258 | + typename assoc_algorithms<ContainerTraits>::reference |
| 259 | + assoc_algorithms<ContainerTraits>::get (container &c, index_param ix) |
| 260 | + { |
| 261 | + iterator iter = find (c, ix); |
| 262 | + |
| 263 | + if (iter == end(c)) |
| 264 | + { |
| 265 | + throw std::domain_error |
| 266 | + (std::string ("associative container: key not found")); |
| 267 | + } |
| 268 | + |
| 269 | + else |
| 270 | + { |
| 271 | + return iter->second; |
| 272 | + } |
| 273 | + } |
| 274 | + |
| 275 | + ///////////////////////////////////////////////////////////////////////// |
| 276 | + // Assign a value at a particular index (associative version) |
| 277 | + ///////////////////////////////////////////////////////////////////////// |
| 278 | + |
| 279 | + template<typename ContainerTraits> |
| 280 | + void |
| 281 | + assoc_algorithms<ContainerTraits>::assign (container &c |
| 282 | + , index_param ix |
| 283 | + , value_param val) |
| 284 | + { |
| 285 | + c[ix] = val; |
| 286 | + } |
| 287 | + |
| 288 | + ///////////////////////////////////////////////////////////////////////// |
| 289 | + // Find an element in an associative container |
| 290 | + ///////////////////////////////////////////////////////////////////////// |
| 291 | + |
| 292 | + template<typename ContainerTraits> |
| 293 | + typename assoc_algorithms<ContainerTraits>::iterator |
| 294 | + assoc_algorithms<ContainerTraits>::find (container &c, key_param key) |
| 295 | + { |
| 296 | + return c.find (key); |
| 297 | + } |
| 298 | + |
| 299 | + ///////////////////////////////////////////////////////////////////////// |
| 300 | + // Count occurances of an element in a container (associative version) |
| 301 | + ///////////////////////////////////////////////////////////////////////// |
| 302 | + |
| 303 | + template<typename ContainerTraits> |
| 304 | + typename assoc_algorithms<ContainerTraits>::size_type |
| 305 | + assoc_algorithms<ContainerTraits>::count (container &c, key_param key) |
| 306 | + { |
| 307 | + return c.count (key); |
| 308 | + } |
| 309 | +} |
| 310 | + |
| 311 | +#endif // algorithms_rmg_20030823_included |
0 commit comments