Home | History | Annotate | Download | only in decpp
      1 #ifndef _DESTLUTIL_HPP
      2 #define _DESTLUTIL_HPP
      3 /*-------------------------------------------------------------------------
      4  * drawElements C++ Base Library
      5  * -----------------------------
      6  *
      7  * Copyright 2014 The Android Open Source Project
      8  *
      9  * Licensed under the Apache License, Version 2.0 (the "License");
     10  * you may not use this file except in compliance with the License.
     11  * You may obtain a copy of the License at
     12  *
     13  *      http://www.apache.org/licenses/LICENSE-2.0
     14  *
     15  * Unless required by applicable law or agreed to in writing, software
     16  * distributed under the License is distributed on an "AS IS" BASIS,
     17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     18  * See the License for the specific language governing permissions and
     19  * limitations under the License.
     20  *
     21  *//*!
     22  * \file
     23  * \brief Utilities for STL containers.
     24  *//*--------------------------------------------------------------------*/
     25 
     26 #include "deDefs.hpp"
     27 
     28 #include <algorithm>
     29 #include <stdexcept>
     30 #include <utility>
     31 #include <iterator>
     32 
     33 namespace de
     34 {
     35 
     36 void STLUtil_selfTest (void);
     37 
     38 //! Test whether `item` is a member of `container`. The type `C` must be an
     39 //! AssociativeContainer.
     40 
     41 template<typename C>
     42 inline bool contains (const C& container, const typename C::key_type& item)
     43 {
     44 	const typename C::const_iterator it = container.find(item);
     45 	return (it != container.end());
     46 }
     47 
     48 template<typename I, typename K>
     49 inline bool contains (const I& begin, const I& end, const K& item)
     50 {
     51 	const I it = std::find(begin, end, item);
     52 	return (it != end);
     53 }
     54 
     55 template<typename C>
     56 C intersection (const C& s1, const C& s2)
     57 {
     58 	C ret;
     59 	std::set_intersection(s1.begin(), s1.end(), s2.begin(), s2.end(),
     60 						  std::insert_iterator<C>(ret, ret.begin()));
     61 	return ret;
     62 }
     63 
     64 template<typename C>
     65 C set_union (const C& s1, const C& s2)
     66 {
     67 	C ret;
     68 	std::set_union(s1.begin(), s1.end(), s2.begin(), s2.end(),
     69 				   std::insert_iterator<C>(ret, ret.begin()));
     70 	return ret;
     71 }
     72 
     73 // Utilities for map-like container types
     74 
     75 //! Return a pointer to the value mapped to `key`, or null if not found.
     76 template <typename M>
     77 const typename M::mapped_type* tryLookup (const M& map,
     78 										  const typename M::key_type& key)
     79 {
     80 	typename M::const_iterator it = map.find(key);
     81 	if (it == map.end())
     82 		return DE_NULL;
     83 	return &it->second;
     84 }
     85 
     86 //! Return a reference to the value mapped to `key`, or `fallback` if not found.
     87 template<typename M>
     88 const typename M::mapped_type& lookupDefault (const M&							map,
     89 											  const typename M::key_type&		key,
     90 											  const typename M::mapped_type&	fallback)
     91 {
     92 	const typename M::mapped_type* ptr = tryLookup(map, key);
     93 	return ptr == DE_NULL ? fallback : *ptr;
     94 }
     95 
     96 //! Return a reference to the value mapped to `key`, or raise
     97 //! `std::out_of_range` if not found.
     98 template<typename M>
     99 const typename M::mapped_type& lookup (const M& map, const typename M::key_type& key)
    100 {
    101 	const typename M::mapped_type* ptr = tryLookup(map, key);
    102 	if (ptr == DE_NULL)
    103 		throw std::out_of_range("key not found in map");
    104 	return *ptr;
    105 }
    106 
    107 //! Map `key` to `value`. This differs from `map[key] = value` in that there
    108 //! is no default construction and assignment involved.
    109 template<typename M>
    110 bool insert (M& map, const typename M::key_type& key, const typename M::mapped_type& value)
    111 {
    112 	typename M::value_type entry(key, value);
    113 	std::pair<typename M::iterator,bool> ret = map.insert(entry);
    114 	return ret.second;
    115 }
    116 
    117 } // de
    118 
    119 #endif // _DESTLUTIL_HPP
    120