Lumiera  0.pre.03
»edit your freedom«
util-coll.hpp
Go to the documentation of this file.
1 /*
2  UTIL-COLL.hpp - helpers and convenience shortcuts for working with collections
3 
4  Copyright (C) Lumiera.org
5  2012, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 */
22 
23 
43 #ifndef UTIL_COLL_H
44 #define UTIL_COLL_H
45 
46 #include "lib/util.hpp"
47 #include "lib/meta/trait.hpp"
48 
49 #include <limits>
50 
51 
52 
53 namespace util {
54 
56  using lib::meta::disable_if;
57 
58  namespace { // predicates to pick the right implementation
59 
60  using lib::meta::Yes_t;
61  using lib::meta::No_t;
62 
63  template<typename T>
65  {
66  typedef typename lib::meta::Unwrap<T>::Type TaT;
67 
70  };
71  };
72 
73  template<typename T>
75  {
77  };
78  };
79 
80  template<typename T>
82  {
83  typedef typename lib::meta::Unwrap<T>::Type TaT;
84 
86  };
87  };
88 
89 
90  template<typename COL>
91  inline void
92  __ensure_nonempty(COL const& coll)
93  {
94  if (util::isnil(coll))
95  throw lumiera::error::Logic("attempt to access the first element of an empty collection"
96  ,lumiera::error::LUMIERA_ERROR_BOTTOM_VALUE);
97  }
98  }
99 
100 
101 
102 
103  /* === specialisations for STL-like containers and Lumiera Forward Iterators === */
104 
109  template <typename COLL>
110  inline enable_if< treat_as_STL_Container<COLL>,
111  typename COLL::reference >
112  first (COLL const& coll)
113  {
114  using lib::meta::unwrap;
115 
116  __ensure_nonempty(coll);
117  return *(unwrap(coll).begin());
118  }
119 
120 
125  template <typename COLL>
126  inline enable_if< can_direct_access_Last<COLL>,
127  typename COLL::reference >
128  last (COLL const& coll)
129  {
130  using lib::meta::unwrap;
131 
132  __ensure_nonempty(coll);
133  return *(unwrap(coll).rbegin());
134  }
135 
136 
137 
141  template <typename IT>
142  inline enable_if< treat_as_LumieraIterator<IT>,
143  typename IT::reference >
144  first (IT ii)
145  {
146  __ensure_nonempty(ii);
147  return *ii;
148  }
149 
150 
151 #ifdef LIB_ITERTOOLS_H
152 
157  template <typename IT>
158  inline enable_if< treat_as_LumieraIterator<IT>,
159  typename IT::value_type >
160  last (IT ii)
161  {
162  __ensure_nonempty(ii);
163  return lib::pull_last (ii);
164  }
165 #endif
166 
167 
168 
169  /* === generic container helpers === */
170 
171  template<class IT>
172  inline auto
173  max (IT&& elms)
174  {
175  using Val = typename std::remove_reference_t<IT>::value_type;
176  Val res = std::numeric_limits<Val>::min();
177  for (auto const& elm : std::forward<IT> (elms))
178  if (elm > res)
179  res = elm;
180  return res;
181  }
182 
183  template<class CON>
184  inline auto
185  max (CON const& elms)
186  {
187  using Val = typename std::remove_reference_t<CON>::value_type;
188  Val res = std::numeric_limits<Val>::min();
189  for (auto const& elm : elms)
190  if (elm > res)
191  res = elm;
192  return res;
193  }
194 
195 
196  template<class IT>
197  inline auto
198  min (IT&& elms)
199  {
200  using Val = typename std::remove_reference_t<IT>::value_type;
201  Val res = std::numeric_limits<Val>::max();
202  for (auto const& elm : std::forward<IT> (elms))
203  if (elm < res)
204  res = elm;
205  return res;
206  }
207 
208  template<class CON>
209  inline auto
210  min (CON const& elms)
211  {
212  using Val = typename std::remove_reference_t<CON>::value_type;
213  Val res = std::numeric_limits<Val>::max();
214  for (auto const& elm : elms)
215  if (elm < res)
216  res = elm;
217  return res;
218  }
219 
220 
221 
222 } // namespace util
223 #endif /*UTIL_COLL_H*/
Trait template to detect a type usable with the STL for-each loop.
Definition: trait.hpp:550
Trait template to detect a type also supporting STL-style backwards iteration.
Definition: trait.hpp:614
enable_if< treat_as_STL_Container< COLL >, typename COLL::reference > first(COLL const &coll)
access the first element of a STL-like container.
Definition: util-coll.hpp:112
typename enable_if_c< Cond::value, T >::type enable_if
SFINAE helper to control the visibility of specialisations and overloads.
Definition: meta/util.hpp:92
Derived specific exceptions within Lumiera&#39;s exception hierarchy.
Definition: error.hpp:199
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
Trait template to detect a type usable immediately as "Lumiera Forward Iterator" in a specialised for...
Definition: trait.hpp:505
char Yes_t
helper types to detect the overload resolution chosen by the compiler
Definition: meta/util.hpp:104
Helpers for type detection, type rewriting and metaprogramming.
enable_if< can_direct_access_Last< COLL >, typename COLL::reference > last(COLL const &coll)
access the last element of a STL-like container.
Definition: util-coll.hpp:128