KeyValuePair.h
Go to the documentation of this file.
1 /*!
2  *
3  *
4  * \brief Provides a pair of Key and Value, as well as functions working with them.
5  *
6  *
7  *
8  *
9  * \author Oswin Krause
10  * \date 2012
11  *
12  *
13  * \par Copyright 1995-2015 Shark Development Team
14  *
15  * <BR><HR>
16  * This file is part of Shark.
17  * <http://image.diku.dk/shark/>
18  *
19  * Shark is free software: you can redistribute it and/or modify
20  * it under the terms of the GNU Lesser General Public License as published
21  * by the Free Software Foundation, either version 3 of the License, or
22  * (at your option) any later version.
23  *
24  * Shark is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27  * GNU Lesser General Public License for more details.
28  *
29  * You should have received a copy of the GNU Lesser General Public License
30  * along with Shark. If not, see <http://www.gnu.org/licenses/>.
31  *
32  */
33 #ifndef SHARK_CORE_KEY_VALUE_PAIR_H
34 #define SHARK_CORE_KEY_VALUE_PAIR_H
35 
37 
38 #include <boost/operators.hpp>
39 
40 #include <functional>//std::less
41 namespace shark{
42 
43 ///\brief Represents a Key-Value-Pair similar std::pair which is strictly ordered by it's key
44 ///
45 ///Key must be less-than comparable using operator<
46 template<class Key, class Value>
48 :boost::partially_ordered<KeyValuePair<Key,Value> >{
49  Key key;
50  Value value;
51 
52  KeyValuePair():key(), value(){}
53  KeyValuePair(Key const& key, Value const& value)
54  :key(key),value(value){}
55 
56  template<class Pair>
57  KeyValuePair(Pair const& pair)
58  :key(pair.key),value(pair.value){}
59 
60  template<class K, class V>
61  bool operator==(KeyValuePair<K,V> const& pair) const{
62  return key == pair.key;
63  }
64  template<class K, class V>
65  bool operator<(KeyValuePair<K,V> const& pair) const{
66  return key<pair.key;
67  }
68 };
69 
70 ///\brief Swaps the contents of two instances of KeyValuePair
71 template<class K, class V>
73  using std::swap;
74  swap(pair1.key,pair2.key);
75  swap(pair1.value,pair2.value);
76 }
77 
78 ///\brief Creates a KeyValuePair
79 template<class Key, class Value>
82 }
83 
84 
85 /// \cond
86 
87 ///\brief Reference type used by zipKeyValuePair
88 template<class Key, class Value,class KeyIterator, class ValueIterator>
89 struct PairReference<KeyValuePair<Key,Value>, KeyIterator, ValueIterator >{
90 private:
91  typedef typename boost::iterator_reference<KeyIterator>::type KeyReference;
92  typedef typename boost::iterator_reference<ValueIterator>::type ValueReference;
93  typedef KeyValuePair<Key,Value> ReferedType;
94 public:
95  struct type
96  :boost::partially_ordered<type,ReferedType >{
97  KeyReference key;
98  ValueReference value;
99 
100  type(
101  KeyReference key,
102  ValueReference value
103  ):key(key),value(value){}
104 
105  template<class K, class V>
106  type(
107  KeyValuePair<K,V> const& pair
108  ):key(pair.key),value(pair.value){}
109 
110  template<class Reference>
111  type& operator=(Reference const& pair){
112  key = pair.key;
113  value = pair.value;
114  return *this;
115  }
116  type& operator=(type const& pair){
117  key = pair.key;
118  value = pair.value;
119  return *this;
120  }
121 
122  template<class T>
123  bool operator==(T const& pair) const{
124  return key == pair.key;
125  }
126  template<class T>
127  bool operator<(T const& pair) const{
128  return key < pair.key;
129  }
130 
131  operator ReferedType()const{
132  return ReferedType(key,value);
133  }
134 
135  friend void swap(type a, type b){
136  using std::swap;
137  swap(a.key,b.key);
138  swap(a.value,b.value);
139  }
140  };
141 };
142 
143 /// \endcond
144 
145 template<
146  class Iterator1,
147  class Iterator2
148 >
150 public boost::iterator_range<
151  PairIterator<
152  KeyValuePair<
153  typename boost::iterator_value<Iterator1>::type,
154  typename boost::iterator_value<Iterator2>::type
155  >,
156  Iterator1,Iterator2
157  >
158 >{
159  typedef KeyValuePair<
160  typename boost::iterator_value<Iterator1>::type,
161  typename boost::iterator_value<Iterator2>::type
162  > value_type;
164  typedef boost::iterator_range<iterator> base_type;
165 
166  template<class Range1, class Range2>
167  KeyValueRange(Range1& range1, Range2& range2)
168  :base_type(zipPairRange<value_type>(range1, range2)){}
169 
170  KeyValueRange(Iterator1 begin1, Iterator1 end1, Iterator2 begin2, Iterator2 end2)
171  :base_type(zipPairRange<value_type>(begin1, end1, begin2, end2)){}
172 
174 };
175 
176 ///\brief Zips two ranges together, interpreting the first range as Key which can be sorted.
177 ///
178 ///\param begin1 beginning of first range
179 ///\param end1 end of first range
180 ///\param begin2 beginning of second range
181 ///\param end2 end of second range
182 template<class Iterator1,class Iterator2>
184 zipKeyValuePairs(Iterator1 begin1, Iterator1 end1, Iterator2 begin2, Iterator2 end2){
185  return KeyValueRange<Iterator1,Iterator2>(begin1,end1,begin2,end2);
186 }
187 
188 
189 ///\brief Zips two ranges together, interpreting the first range as Key which can be sorted.
190 ///
191 ///\param range1 The Key range
192 ///\param range2 The value range
193 template<class Range1,class Range2>
195  typename boost::range_iterator<Range1>::type,
196  typename boost::range_iterator<Range2>::type
197 >
198 zipKeyValuePairs(Range1& range1, Range2& range2){
199  return KeyValueRange<
200  typename boost::range_iterator<Range1>::type,
201  typename boost::range_iterator<Range2>::type>(range1,range2);
202 }
203 
204 }
205 #endif