annotate DEPENDENCIES/generic/include/boost/icl/concept/element_associator.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 /*-----------------------------------------------------------------------------+
Chris@16 2 Copyright (c) 2010-2010: Joachim Faulhaber
Chris@16 3 +------------------------------------------------------------------------------+
Chris@16 4 Distributed under the Boost Software License, Version 1.0.
Chris@16 5 (See accompanying file LICENCE.txt or copy at
Chris@16 6 http://www.boost.org/LICENSE_1_0.txt)
Chris@16 7 +-----------------------------------------------------------------------------*/
Chris@16 8 #ifndef BOOST_ICL_CONCEPT_ELEMENT_ASSOCIATOR_HPP_JOFA_100921
Chris@16 9 #define BOOST_ICL_CONCEPT_ELEMENT_ASSOCIATOR_HPP_JOFA_100921
Chris@16 10
Chris@16 11 #include <boost/config.hpp>
Chris@16 12 #include <boost/icl/type_traits/is_associative_element_container.hpp>
Chris@16 13 #include <boost/icl/type_traits/is_key_container_of.hpp>
Chris@16 14 #include <boost/icl/type_traits/is_combinable.hpp>
Chris@16 15 #include <boost/icl/detail/subset_comparer.hpp>
Chris@16 16 #include <boost/icl/concept/element_set.hpp>
Chris@16 17 #include <boost/icl/concept/element_map.hpp>
Chris@16 18
Chris@16 19 namespace boost{ namespace icl
Chris@16 20 {
Chris@16 21
Chris@16 22 //==============================================================================
Chris@16 23 //= Size
Chris@16 24 //==============================================================================
Chris@16 25 template<class Type>
Chris@16 26 typename enable_if<is_element_container<Type>, std::size_t>::type
Chris@16 27 iterative_size(const Type& object)
Chris@16 28 {
Chris@16 29 return object.size();
Chris@16 30 }
Chris@16 31
Chris@16 32 template<class Type>
Chris@16 33 typename enable_if<is_associative_element_container<Type>, typename Type::size_type>::type
Chris@16 34 size(const Type& object)
Chris@16 35 {
Chris@16 36 return icl::iterative_size(object);
Chris@16 37 }
Chris@16 38
Chris@16 39 template<class Type>
Chris@16 40 typename enable_if<is_associative_element_container<Type>, typename Type::size_type>::type
Chris@16 41 cardinality(const Type& object)
Chris@16 42 {
Chris@16 43 return icl::iterative_size(object);
Chris@16 44 }
Chris@16 45
Chris@16 46
Chris@16 47 //==============================================================================
Chris@16 48 //= Containedness<ElementSet|ElementMap>
Chris@16 49 //==============================================================================
Chris@16 50 //------------------------------------------------------------------------------
Chris@16 51 //- bool within(c P&, c T&) T:{s}|{m} P:{e}|{i} fragment_types|key_types
Chris@16 52 //------------------------------------------------------------------------------
Chris@16 53 /** Checks if a key is in the associative container */
Chris@16 54 template<class Type>
Chris@16 55 typename enable_if<is_associative_element_container<Type>, bool>::type
Chris@16 56 within(const typename Type::key_type& key, const Type& super)
Chris@16 57 {
Chris@16 58 return !(super.find(key) == super.end());
Chris@16 59 }
Chris@16 60
Chris@16 61 //------------------------------------------------------------------------------
Chris@16 62 //- bool within(c P&, c T&) T:{s}|{m} P:{s'} fragment_types|key_types
Chris@16 63 //------------------------------------------------------------------------------
Chris@16 64 template<class SubT, class SuperT>
Chris@16 65 typename enable_if<mpl::and_< is_associative_element_container<SuperT>
Chris@16 66 , is_key_container_of<SubT, SuperT> >,
Chris@16 67 bool>::type
Chris@16 68 within(const SubT& sub, const SuperT& super)
Chris@16 69 {
Chris@16 70 if(icl::is_empty(sub)) return true;
Chris@16 71 if(icl::is_empty(super)) return false;
Chris@16 72 if(icl::size(super) < icl::size(sub)) return false;
Chris@16 73
Chris@16 74 typename SubT::const_iterator common_lwb_;
Chris@16 75 typename SubT::const_iterator common_upb_;
Chris@16 76 if(!Set::common_range(common_lwb_, common_upb_, sub, super))
Chris@16 77 return false;
Chris@16 78
Chris@16 79 typename SubT::const_iterator sub_ = sub.begin();
Chris@16 80 typename SuperT::const_iterator super_;
Chris@16 81 while(sub_ != sub.end())
Chris@16 82 {
Chris@16 83 super_ = super.find(key_value<SubT>(sub_));
Chris@16 84 if(super_ == super.end())
Chris@16 85 return false;
Chris@16 86 else if(!co_equal(sub_, super_, &sub, &super))
Chris@16 87 return false;
Chris@16 88
Chris@16 89 ++sub_;
Chris@16 90 }
Chris@16 91 return true;
Chris@16 92 }
Chris@16 93
Chris@16 94 //------------------------------------------------------------------------------
Chris@16 95 //- bool contains(c T&, c P&) T:{s}|{m} P:{e}|{i} fragment_types|key_types
Chris@16 96 //------------------------------------------------------------------------------
Chris@16 97 template<class Type>
Chris@16 98 typename enable_if<is_associative_element_container<Type>, bool>::type
Chris@16 99 contains(const Type& super, const typename Type::key_type& key)
Chris@16 100 {
Chris@16 101 return icl::within(key, super);
Chris@16 102 }
Chris@16 103
Chris@16 104 //------------------------------------------------------------------------------
Chris@16 105 //- bool contains(c T&, c P&) T:{s}|{m} P:{s'} fragment_types|key_types
Chris@16 106 //------------------------------------------------------------------------------
Chris@16 107 template<class SubT, class SuperT>
Chris@16 108 typename enable_if<mpl::and_< is_associative_element_container<SuperT>
Chris@16 109 , is_key_container_of<SubT, SuperT> >,
Chris@16 110 bool>::type
Chris@16 111 contains(const SuperT& super, const SubT& sub)
Chris@16 112 {
Chris@16 113 return icl::within(sub, super);
Chris@16 114 }
Chris@16 115
Chris@16 116 //==============================================================================
Chris@16 117 //= Equivalences and Orderings
Chris@16 118 //==============================================================================
Chris@16 119
Chris@16 120 #ifdef BOOST_MSVC
Chris@16 121 #pragma warning(push)
Chris@16 122 #pragma warning(disable:4996) //'std::equal': Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators'
Chris@16 123 #endif // I do guarantee here that I am using the parameters correctly :)
Chris@16 124
Chris@16 125 /** Standard equality, which is lexicographical equality of the sets
Chris@16 126 as sequences, that are given by their Compare order. */
Chris@16 127 template<class Type>
Chris@16 128 inline typename enable_if<is_associative_element_container<Type>, bool>::type
Chris@16 129 operator == (const Type& left, const Type& right)
Chris@16 130 {
Chris@16 131 return left.size() == right.size()
Chris@16 132 && std::equal(left.begin(), left.end(), right.begin());
Chris@16 133 }
Chris@16 134
Chris@16 135 #ifdef BOOST_MSVC
Chris@16 136 #pragma warning(pop)
Chris@16 137 #endif
Chris@16 138
Chris@16 139 template<class Type>
Chris@16 140 inline typename enable_if<is_associative_element_container<Type>, bool>::type
Chris@16 141 is_element_equal(const Type& left, const Type& right)
Chris@16 142 { return left == right; }
Chris@16 143
Chris@16 144
Chris@16 145 /* Strict weak less ordering which is given by the Compare order */
Chris@16 146 template<class Type>
Chris@16 147 inline typename enable_if<is_associative_element_container<Type>, bool>::type
Chris@16 148 operator < (const Type& left, const Type& right)
Chris@16 149 {
Chris@16 150 return std::lexicographical_compare(
Chris@16 151 left.begin(), left.end(), right.begin(), right.end(),
Chris@16 152 typename Type::element_compare()
Chris@16 153 );
Chris@16 154 }
Chris@16 155
Chris@16 156 template<class LeftT, class RightT>
Chris@16 157 typename enable_if<is_concept_equivalent<is_element_container,LeftT, RightT>,
Chris@16 158 int>::type
Chris@16 159 inclusion_compare(const LeftT& left, const RightT& right)
Chris@16 160 {
Chris@16 161 return Set::subset_compare(left, right,
Chris@16 162 left.begin(), left.end(),
Chris@16 163 right.begin(), right.end());
Chris@16 164 }
Chris@16 165
Chris@16 166 //==============================================================================
Chris@16 167 //= Addition
Chris@16 168 //==============================================================================
Chris@16 169 template <class Type>
Chris@16 170 inline typename enable_if<is_associative_element_container<Type>, Type>::type&
Chris@16 171 operator += (Type& object, const typename Type::value_type& operand)
Chris@16 172 {
Chris@16 173 return icl::add(object, operand);
Chris@16 174 }
Chris@16 175
Chris@16 176 template <class Type>
Chris@16 177 inline typename enable_if<is_associative_element_container<Type>, Type>::type
Chris@16 178 operator + (Type object, const typename Type::value_type& operand)
Chris@16 179 {
Chris@16 180 return object += operand;
Chris@16 181 }
Chris@16 182
Chris@16 183 template <class Type>
Chris@16 184 inline typename enable_if<is_associative_element_container<Type>, Type>::type
Chris@16 185 operator + (const typename Type::value_type& operand, Type object)
Chris@16 186 {
Chris@16 187 return object += operand;
Chris@16 188 }
Chris@16 189
Chris@16 190 template <class Type>
Chris@16 191 inline typename enable_if<is_associative_element_container<Type>, Type>::type&
Chris@16 192 operator += (Type& object, const Type& operand)
Chris@16 193 {
Chris@16 194 if(&object == &operand)
Chris@16 195 return object;
Chris@16 196
Chris@16 197 typename Type::iterator prior_ = object.end();
Chris@16 198 ICL_const_FORALL(typename Type, it_, operand)
Chris@16 199 prior_ = icl::add(object, prior_, *it_);
Chris@16 200
Chris@16 201 return object;
Chris@16 202 }
Chris@16 203
Chris@16 204 template <class Type>
Chris@16 205 inline typename enable_if<is_associative_element_container<Type>, Type>::type
Chris@16 206 operator + (Type object, const Type& operand)
Chris@16 207 {
Chris@16 208 return object += operand;
Chris@16 209 }
Chris@16 210
Chris@16 211 //==============================================================================
Chris@16 212 template <class Type>
Chris@16 213 inline typename enable_if<is_associative_element_container<Type>, Type>::type&
Chris@16 214 operator |= (Type& object, const typename Type::value_type& operand)
Chris@16 215 {
Chris@16 216 return icl::add(object, operand);
Chris@16 217 }
Chris@16 218
Chris@16 219 template <class Type>
Chris@16 220 inline typename enable_if<is_associative_element_container<Type>, Type>::type
Chris@16 221 operator | (Type object, const typename Type::value_type& operand)
Chris@16 222 {
Chris@16 223 return object += operand;
Chris@16 224 }
Chris@16 225
Chris@16 226 template <class Type>
Chris@16 227 inline typename enable_if<is_associative_element_container<Type>, Type>::type
Chris@16 228 operator | (const typename Type::value_type& operand, Type object)
Chris@16 229 {
Chris@16 230 return object += operand;
Chris@16 231 }
Chris@16 232
Chris@16 233 template <class Type>
Chris@16 234 inline typename enable_if<is_associative_element_container<Type>, Type>::type&
Chris@16 235 operator |= (Type& object, const Type& operand)
Chris@16 236 {
Chris@16 237 return object += operand;
Chris@16 238 }
Chris@16 239
Chris@16 240 template <class Type>
Chris@16 241 inline typename enable_if<is_associative_element_container<Type>, Type>::type
Chris@16 242 operator | (Type object, const Type& operand)
Chris@16 243 {
Chris@16 244 return object += operand;
Chris@16 245 }
Chris@16 246
Chris@16 247
Chris@16 248 //==============================================================================
Chris@16 249 //= Insertion
Chris@16 250 //==============================================================================
Chris@16 251 //------------------------------------------------------------------------------
Chris@16 252 //- V insert(T&, c P&) T:{s}|{m} P:{e}|{b} fragment_type
Chris@16 253 //------------------------------------------------------------------------------
Chris@16 254 template<class Type>
Chris@16 255 typename enable_if<is_associative_element_container<Type>,
Chris@16 256 std::pair<typename Type::iterator,bool> >::type
Chris@16 257 insert(Type& object, const typename Type::value_type& operand)
Chris@16 258 {
Chris@16 259 return object.insert(operand);
Chris@16 260 }
Chris@16 261
Chris@16 262 template<class Type>
Chris@16 263 typename enable_if<is_associative_element_container<Type>,
Chris@16 264 typename Type::iterator>::type
Chris@16 265 insert(Type& object, typename Type::iterator prior,
Chris@16 266 const typename Type::value_type& operand)
Chris@16 267 {
Chris@16 268 return object.insert(prior, operand);
Chris@16 269 }
Chris@16 270
Chris@16 271 //------------------------------------------------------------------------------
Chris@16 272 //- T insert(T&, c T&) T:{s m} map fragment_type
Chris@16 273 //------------------------------------------------------------------------------
Chris@16 274 template<class Type>
Chris@16 275 typename enable_if<is_associative_element_container<Type>, Type>::type&
Chris@16 276 insert(Type& object, const Type& addend)
Chris@16 277 {
Chris@16 278 typedef typename Type::iterator iterator;
Chris@16 279
Chris@16 280 iterator prior_ = object.end();
Chris@16 281 ICL_const_FORALL(typename Type, elem_, addend)
Chris@16 282 icl::insert(object, prior_, *elem_);
Chris@16 283
Chris@16 284 return object;
Chris@16 285 }
Chris@16 286
Chris@16 287
Chris@16 288 //==============================================================================
Chris@16 289 //= Erasure
Chris@16 290 //==============================================================================
Chris@16 291 template<class Type>
Chris@16 292 typename enable_if<is_associative_element_container<Type>, typename Type::size_type>::type
Chris@16 293 erase(Type& object, const typename Type::key_type& key_value)
Chris@16 294 {
Chris@16 295 typedef typename Type::size_type size_type;
Chris@16 296 typename Type::iterator it_ = object.find(key_value);
Chris@16 297 if(it_ != object.end())
Chris@16 298 {
Chris@16 299 object.erase(it_);
Chris@16 300 return unit_element<size_type>::value();
Chris@16 301 }
Chris@16 302 return identity_element<size_type>::value();
Chris@16 303 }
Chris@16 304
Chris@16 305 template<class Type>
Chris@16 306 typename enable_if<is_associative_element_container<Type>, Type>::type&
Chris@16 307 erase(Type& object, const Type& erasure)
Chris@16 308 {
Chris@16 309 ICL_const_FORALL(typename Type, elem_, erasure)
Chris@16 310 icl::erase(object, *elem_);
Chris@16 311
Chris@16 312 return object;
Chris@16 313 }
Chris@16 314
Chris@16 315
Chris@16 316
Chris@16 317 //==============================================================================
Chris@16 318 //= Subtraction<ElementSet|ElementMap>
Chris@16 319 //==============================================================================
Chris@16 320 template <class Type>
Chris@16 321 inline typename enable_if<is_associative_element_container<Type>, Type>::type&
Chris@16 322 operator -= (Type& object, const typename Type::value_type& operand)
Chris@16 323 {
Chris@16 324 return icl::subtract(object, operand);
Chris@16 325 }
Chris@16 326
Chris@16 327 template <class Type>
Chris@16 328 inline typename enable_if<is_associative_element_container<Type>, Type>::type
Chris@16 329 operator - (Type object, const typename Type::value_type& operand)
Chris@16 330 {
Chris@16 331 return object -= operand;
Chris@16 332 }
Chris@16 333
Chris@16 334 template <class Type>
Chris@16 335 inline typename enable_if<is_associative_element_container<Type>, Type>::type&
Chris@16 336 operator -= (Type& object, const Type& subtrahend)
Chris@16 337 {
Chris@16 338 ICL_const_FORALL(typename Type, it_, subtrahend)
Chris@16 339 icl::subtract(object, *it_);
Chris@16 340
Chris@16 341 return object;
Chris@16 342 }
Chris@16 343
Chris@16 344 template <class Type>
Chris@16 345 inline typename enable_if<is_associative_element_container<Type>, Type>::type
Chris@16 346 operator - (Type object, const Type& subtrahend)
Chris@16 347 {
Chris@16 348 return object -= subtrahend;
Chris@16 349 }
Chris@16 350
Chris@16 351
Chris@16 352 //==============================================================================
Chris@16 353 //= Intersection
Chris@16 354 //==============================================================================
Chris@16 355 //------------------------------------------------------------------------------
Chris@16 356 //- void add_intersection(T&, c T&, c P&) T:{s}{m} P:{e}{e} key_type
Chris@16 357 //------------------------------------------------------------------------------
Chris@16 358 template<class Type>
Chris@16 359 inline typename enable_if<is_associative_element_container<Type>, void>::type
Chris@16 360 add_intersection(Type& section, const Type& object,
Chris@16 361 const typename Type::key_type& operand)
Chris@16 362 {
Chris@16 363 typedef typename Type::const_iterator const_iterator;
Chris@16 364 const_iterator it_ = object.find(operand);
Chris@16 365 if(it_ != object.end())
Chris@16 366 icl::add(section, *it_);
Chris@16 367 }
Chris@16 368
Chris@16 369 //------------------------------------------------------------------------------
Chris@16 370 //- void add_intersection(T&, c T&, c P&) T:{s}{m} P:{s}{s} set key_type
Chris@16 371 //------------------------------------------------------------------------------
Chris@16 372 template<class Type>
Chris@16 373 inline typename enable_if<is_associative_element_container<Type>, void>::type
Chris@16 374 add_intersection(Type& section, const Type& object,
Chris@16 375 const typename key_container_type_of<Type>::type& operand)
Chris@16 376 {
Chris@16 377 typedef typename key_container_type_of<Type>::type key_container_type;
Chris@16 378 typedef typename key_container_type::const_iterator const_iterator;
Chris@16 379 const_iterator common_lwb_, common_upb_;
Chris@16 380 if(!Set::common_range(common_lwb_, common_upb_, operand, object))
Chris@16 381 return;
Chris@16 382
Chris@16 383 const_iterator sec_ = common_lwb_;
Chris@16 384 while(sec_ != common_upb_)
Chris@16 385 add_intersection(section, object, *sec_++);
Chris@16 386 }
Chris@16 387
Chris@16 388 //------------------------------------------------------------------------------
Chris@16 389 //- Intersection<ElementMap|ElementSet>
Chris@16 390 //------------------------------------------------------------------------------
Chris@16 391 template<class Type>
Chris@16 392 inline typename enable_if<is_associative_element_container<Type>, Type>::type&
Chris@16 393 operator &= (Type& object, const typename Type::key_type& operand)
Chris@16 394 {
Chris@16 395 Type section;
Chris@16 396 add_intersection(section, object, operand);
Chris@16 397 object.swap(section);
Chris@16 398 return object;
Chris@16 399 }
Chris@16 400
Chris@16 401 template<class Type>
Chris@16 402 inline typename enable_if<is_associative_element_container<Type>, Type>::type
Chris@16 403 operator & (Type object, const typename Type::key_type& operand)
Chris@16 404 {
Chris@16 405 return object &= operand;
Chris@16 406 }
Chris@16 407
Chris@16 408 template<class Type>
Chris@16 409 inline typename enable_if<is_associative_element_container<Type>, Type>::type
Chris@16 410 operator & (const typename Type::key_type& operand, Type object)
Chris@16 411 {
Chris@16 412 return object &= operand;
Chris@16 413 }
Chris@16 414
Chris@16 415 template<class Type>
Chris@16 416 inline typename enable_if<is_associative_element_container<Type>, Type>::type&
Chris@16 417 operator &= (Type& object, const typename key_container_type_of<Type>::type& operand)
Chris@16 418 {
Chris@16 419 Type section;
Chris@16 420 add_intersection(section, object, operand);
Chris@16 421 object.swap(section);
Chris@16 422 return object;
Chris@16 423 }
Chris@16 424
Chris@16 425 template<class Type>
Chris@16 426 inline typename enable_if<is_associative_element_container<Type>, Type>::type
Chris@16 427 operator & (Type object, const Type& operand)
Chris@16 428 {
Chris@16 429 return object &= operand;
Chris@16 430 }
Chris@16 431 //------------------------------------------------------------------------------
Chris@16 432
Chris@16 433 template<class Type, class CoType>
Chris@16 434 inline typename enable_if<is_associative_element_container<Type>, bool>::type
Chris@16 435 disjoint(const Type& left, const Type& right)
Chris@16 436 {
Chris@16 437 return !intersects(left, right);
Chris@16 438 }
Chris@16 439
Chris@16 440 //==============================================================================
Chris@16 441 //= Symmetric difference<ElementSet|ElementMap>
Chris@16 442 //==============================================================================
Chris@16 443 template<class Type>
Chris@16 444 inline typename enable_if<is_associative_element_container<Type>, Type>::type
Chris@16 445 operator ^ (Type object, const typename Type::value_type& operand)
Chris@16 446 {
Chris@16 447 return icl::flip(object, operand);
Chris@16 448 }
Chris@16 449
Chris@16 450 template<class Type>
Chris@16 451 inline typename enable_if<is_associative_element_container<Type>, Type>::type
Chris@16 452 operator ^ (const typename Type::value_type& operand, Type object)
Chris@16 453 {
Chris@16 454 return icl::flip(object, operand);
Chris@16 455 }
Chris@16 456
Chris@16 457 template<class Type>
Chris@16 458 inline typename enable_if<is_associative_element_container<Type>, Type>::type
Chris@16 459 operator ^ (Type object, const Type& operand)
Chris@16 460 {
Chris@16 461 return object ^= operand;
Chris@16 462 }
Chris@16 463
Chris@16 464
Chris@16 465 //==============================================================================
Chris@16 466 //= Manipulation by predicates
Chris@16 467 //==============================================================================
Chris@16 468 template<class Type, class Predicate>
Chris@16 469 typename enable_if<is_associative_element_container<Type>, Type>::type&
Chris@16 470 erase_if(const Predicate& pred, Type& object)
Chris@16 471 {
Chris@16 472 typename Type::iterator it_ = object.begin();
Chris@16 473 while(it_ != object.end())
Chris@16 474 if(pred(*it_))
Chris@16 475 icl::erase(object, it_++);
Chris@16 476 else ++it_;
Chris@16 477 return object;
Chris@16 478 }
Chris@16 479
Chris@16 480 template<class Type, class Predicate>
Chris@16 481 inline typename enable_if<is_associative_element_container<Type>, Type>::type&
Chris@16 482 add_if(const Predicate& pred, Type& object, const Type& src)
Chris@16 483 {
Chris@16 484 typename Type::const_iterator it_ = src.begin();
Chris@16 485 while(it_ != src.end())
Chris@16 486 if(pred(*it_))
Chris@16 487 icl::add(object, *it_++);
Chris@16 488
Chris@16 489 return object;
Chris@16 490 }
Chris@16 491
Chris@16 492 template<class Type, class Predicate>
Chris@16 493 inline typename enable_if<is_associative_element_container<Type>, Type>::type&
Chris@16 494 assign_if(const Predicate& pred, Type& object, const Type& src)
Chris@16 495 {
Chris@16 496 icl::clear(object);
Chris@16 497 return add_if(object, src, pred);
Chris@16 498 }
Chris@16 499
Chris@16 500
Chris@16 501
Chris@16 502 }} // namespace boost icl
Chris@16 503
Chris@16 504 #endif
Chris@16 505
Chris@16 506