Sort all includes in src/gromacs
[alexxy/gromacs.git] / src / gromacs / utility / arrayref.h
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2012,2013,2014, by the GROMACS development team, led by
5  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6  * and including many others, as listed in the AUTHORS file in the
7  * top-level source directory and at http://www.gromacs.org.
8  *
9  * GROMACS is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public License
11  * as published by the Free Software Foundation; either version 2.1
12  * of the License, or (at your option) any later version.
13  *
14  * GROMACS is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with GROMACS; if not, see
21  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
23  *
24  * If you want to redistribute modifications to GROMACS, please
25  * consider that scientific software is very special. Version
26  * control is crucial - bugs must be traceable. We will be happy to
27  * consider code for inclusion in the official distribution, but
28  * derived work must not be called official GROMACS. Details are found
29  * in the README & COPYING files - if they are missing, get the
30  * official version at http://www.gromacs.org.
31  *
32  * To help us fund GROMACS development, we humbly ask that you cite
33  * the research papers on the package. Check out http://www.gromacs.org.
34  */
35 /*! \file
36  * \brief
37  * Declares gmx::ArrayRef and gmx::ConstArrayRef.
38  *
39  * \author Teemu Murtola <teemu.murtola@gmail.com>
40  * \inpublicapi
41  * \ingroup module_utility
42  */
43 #ifndef GMX_UTILITY_ARRAYREF_H
44 #define GMX_UTILITY_ARRAYREF_H
45
46 #include <cstddef>
47
48 #include <iterator>
49 #include <stdexcept>
50 #include <utility>
51 #include <vector>
52
53 #include "gromacs/utility/gmxassert.h"
54
55 namespace gmx
56 {
57
58 /*! \brief
59  * Tag type to initialize empty array references.
60  *
61  * This type (together with appropriate constructors in ArrayRef and
62  * ConstArrayRef) allows initializing any array reference to an empty value
63  * without explicitly specifying its type.  This is convenient when calling
64  * a function that takes an array reference, where constructing an empty
65  * reference explicitly would otherwise require specifying the full array
66  * reference type, including the template parameter.
67  */
68 struct EmptyArrayRef {};
69
70 /*! \brief
71  * STL-like container for an interface to a C array (or part of a std::vector).
72  *
73  * \tparam T  Value type of elements.
74  *
75  * This class provides an interface similar to \c std::vector<T>, with the
76  * following main differences:
77  *  - This class does not have its own storage.  Instead, it references an
78  *    existing array of values (either a C-style array or part of an existing
79  *    std::vector<T>).
80  *  - It is only possible to modify the values themselves through ArrayRef;
81  *    it is not possible to add or remove values.
82  *  - Copying objects of this type is cheap, and the copies behave identically
83  *    to the original object: the copy references the same set of values.
84  *
85  * This class is useful for writing wrappers that expose a different view of
86  * the internal data stored as a single vector/array.
87  *
88  * Methods in this class do not throw, except where indicated.
89  *
90  * Note that due to a Doxygen limitation, the constructor that takes a C array
91  * whose size is known at compile time does not appear in the documentation.
92  *
93  * \todo
94  * This class is not complete.  At least, it should be possible to convert an
95  * ArrayRef to a ConstArrayRef.  There are likely also methods missing (not
96  * required for current usage).
97  *
98  * \inpublicapi
99  * \ingroup module_utility
100  */
101 template <typename T>
102 class ArrayRef
103 {
104     public:
105         //! Type of values stored in the container.
106         typedef T         value_type;
107         //! Type for representing size of the container.
108         typedef size_t    size_type;
109         //! Type for representing difference between two container indices.
110         typedef ptrdiff_t difference_type;
111         //! Const reference to a container element.
112         typedef const T  &const_reference;
113         //! Const pointer to a container element.
114         typedef const T  *const_pointer;
115         //! Const iterator type for the container.
116         typedef const T  *const_iterator;
117         //! Reference to a container element.
118         typedef T        &reference;
119         //! Pointer to a container element.
120         typedef T        *pointer;
121         //! Iterator type for the container.
122         typedef T        *iterator;
123         //! Standard reverse iterator.
124         typedef std::reverse_iterator<iterator>       reverse_iterator;
125         //! Standard reverse iterator.
126         typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
127
128         /*! \brief
129          * Constructs an empty reference.
130          */
131         ArrayRef() : begin_(NULL), end_(NULL) {}
132         /*! \brief
133          * Constructs an empty reference.
134          *
135          * This is provided for convenience, such that EmptyArrayRef can be
136          * used to initialize any ArrayRef, without specifying the template
137          * type.  It is not explicit to enable that usage.
138          */
139         ArrayRef(const EmptyArrayRef &) : begin_(NULL), end_(NULL) {}
140         /*! \brief
141          * Constructs a reference to a particular range.
142          *
143          * \param[in] begin  Pointer to the beginning of a range.
144          * \param[in] end    Pointer to the end of a range.
145          *
146          * Passed pointers must remain valid for the lifetime of this object.
147          *
148          * \note For clarity, use the non-member function arrayRefFromPointers
149          * instead.
150          */
151         ArrayRef(pointer begin, pointer end)
152             : begin_(begin), end_(end)
153         {
154             GMX_ASSERT(end >= begin, "Invalid range");
155         }
156         //! \cond
157         // Doxygen 1.8.5 doesn't parse the declaration correctly...
158         /*! \brief
159          * Constructs a reference to a C array.
160          *
161          * \param[in] array  C array to reference.
162          * \tparam    count  Deduced number of elements in \p array.
163          *
164          * This constructor can only be used with a real array (not with a
165          * pointer).  It constructs a reference to the whole array, without
166          * a need to pass the number of elements explicitly.  The compiler
167          * must be able to deduce the array size.
168          *
169          * Passed array must remain valid for the lifetime of this object.
170          *
171          * This constructor is not explicit to allow directly passing
172          * a C array to a function that takes an ArrayRef parameter.
173          */
174         template <size_t count>
175         ArrayRef(value_type (&array)[count])
176             : begin_(array), end_(array + count)
177         {
178         }
179         //! \endcond
180
181         //! Returns an iterator to the beginning of the container.
182         iterator begin() { return begin_; }
183         //! Returns an iterator to the beginning of the container.
184         const_iterator begin() const { return begin_; }
185         //! Returns an iterator to the end of the container.
186         iterator end() { return end_; }
187         //! Returns an iterator to the end of the container.
188         const_iterator end() const { return end_; }
189         //! Returns an iterator to the reverse beginning of the container.
190         iterator rbegin() { return reverse_iterator(end()); }
191         //! Returns an iterator to the reverse beginning of the container.
192         const_iterator rbegin() const { return reverse_iterator(end()); }
193         //! Returns an iterator to the reverse end of the container.
194         iterator rend() { return reverse_iterator(begin()); }
195         //! Returns an iterator to the reverse end of the container.
196         const_iterator rend() const { return reverse_iterator(begin()); }
197
198         //! Returns the size of the container.
199         size_type size() const { return end_ - begin_; }
200         //! Identical to size().
201         size_type capacity() const { return end_ - begin_; }
202         //! Whether the container is empty.
203         bool empty() const { return begin_ == end_; }
204
205         //! Access container element.
206         reference operator[](size_type n) { return begin_[n]; }
207         //! Access container element.
208         const_reference operator[](size_type n) const { return begin_[n]; }
209         //! Access container element (throws on out-of-range error).
210         reference at(size_type n)
211         {
212             if (n >= size())
213             {
214                 throw std::out_of_range("Vector index out of range");
215             }
216             return begin_[n];
217         }
218         //! Access container element (throws on out-of-range error).
219         const_reference at(size_type n) const
220         {
221             if (n >= size())
222             {
223                 throw std::out_of_range("Vector index out of range");
224             }
225             return begin_[n];
226         }
227         //! Returns the first element in the container.
228         reference front() { return *begin_; }
229         //! Returns the first element in the container.
230         const_reference front() const { return *begin_; }
231         //! Returns the last element in the container.
232         reference back() { return *(end_ - 1); }
233         //! Returns the last element in the container.
234         const_reference back() const { return *(end_ - 1); }
235
236         //! Returns a raw pointer to the contents of the array.
237         pointer data() { return begin_; }
238         //! Returns a raw pointer to the contents of the array.
239         const_pointer data() const { return begin_; }
240
241         /*! \brief
242          * Swaps referenced memory with the other object.
243          *
244          * The actual memory areas are not modified, only the references are
245          * swapped.
246          */
247         void swap(ArrayRef<T> &other)
248         {
249             std::swap(begin_, other.begin_);
250             std::swap(end_, other.end_);
251         }
252
253     private:
254         pointer           begin_;
255         pointer           end_;
256 };
257
258
259 /*! \brief
260  * Constructs a reference to a particular range from two pointers.
261  *
262  * \param[in] begin  Pointer to the beginning of a range.
263  * \param[in] end    Pointer to the end of a range.
264  *
265  * Passed pointers must remain valid for the lifetime of this object.
266  *
267  * \related ArrayRef
268  */
269 template <typename T>
270 ArrayRef<T> arrayRefFromPointers(T * begin, T * end)
271 {
272     return ArrayRef<T>(begin, end);
273 }
274
275 /*! \brief
276  * Constructs a reference to an array
277  *
278  * \param[in] begin  Pointer to the beginning of the array.
279  *                   May be NULL if \p size is zero.
280  * \param[in] size   Number of elements in the array.
281  *
282  * Passed pointer must remain valid for the lifetime of this object.
283  *
284  * \related ArrayRef
285  */
286 template <typename T>
287 ArrayRef<T> arrayRefFromArray(T * begin, size_t size)
288 {
289     return arrayRefFromPointers<T>(begin, begin+size);
290 }
291
292 /*! \brief
293  * Constructs a reference to a particular range in a std::vector.
294  *
295  * \param[in] begin  Iterator to the beginning of a range.
296  * \param[in] end    Iterator to the end of a range.
297  *
298  * The referenced vector must remain valid and not be reallocated for
299  * the lifetime of this object.
300  *
301  * \related ArrayRef
302  */
303 template <typename T>
304 ArrayRef<T> arrayRefFromVector(typename std::vector<T>::iterator begin,
305                                typename std::vector<T>::iterator end)
306 {
307     T * p_begin = (begin != end) ? &*begin : NULL;
308     T * p_end   = p_begin + (end-begin);
309     return arrayRefFromPointers<T>(p_begin, p_end);
310 }
311
312
313
314 /*! \brief
315  * STL-like container for non-mutable interface to a C array (or part of a
316  * std::vector).
317  *
318  * \tparam T  Value type of elements.
319  *
320  * This class provides an interface similar to \c std::vector<T>, with the
321  * following main differences:
322  *  - This class does not have its own storage.  Instead, it references an
323  *    existing array of values (either a C-style array or part of an existing
324  *    std::vector<T>).
325  *  - Only const methods are provided to access the stored values.
326  *    It is not possible to alter the referenced array.
327  *  - Copying objects of this type is cheap, and the copies behave identically
328  *    to the original object: the copy references the same set of values.
329  *
330  * This class is useful for writing wrappers that expose a different view of
331  * the internal data stored as a single vector/array.
332  *
333  * Methods in this class do not throw, except where indicated.
334  *
335  * Note that due to a Doxygen limitation, the constructor that takes a C array
336  * whose size is known at compile time does not appear in the documentation.
337  *
338  * \inpublicapi
339  * \ingroup module_utility
340  */
341 template <typename T>
342 class ConstArrayRef
343 {
344     public:
345         //! Type of values stored in the container.
346         typedef T         value_type;
347         //! Type for representing size of the container.
348         typedef size_t    size_type;
349         //! Type for representing difference between two container indices.
350         typedef ptrdiff_t difference_type;
351         //! Const reference to a container element.
352         typedef const T  &const_reference;
353         //! Const pointer to a container element.
354         typedef const T  *const_pointer;
355         //! Const iterator type for the container.
356         typedef const T  *const_iterator;
357         //! Equal to \a const_reference since changes are not allowed.
358         typedef const_reference reference;
359         //! Equal to \a const_pointer since changes are not allowed.
360         typedef const_pointer   pointer;
361         //! Equal to \a const_iterator since changes are not allowed.
362         typedef const_iterator  iterator;
363         //! Standard reverse iterator.
364         typedef std::reverse_iterator<iterator>       reverse_iterator;
365         //! Standard reverse iterator.
366         typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
367
368         /*! \brief
369          * Constructs an empty reference.
370          */
371         ConstArrayRef() : begin_(NULL), end_(NULL) {}
372         /*! \brief
373          * Constructs an empty reference.
374          *
375          * This is provided for convenience, such that EmptyArrayRef can be
376          * used to initialize any Const ArrayRef, without specifying the
377          * template type.  It is not explicit to enable that usage.
378          */
379         ConstArrayRef(const EmptyArrayRef &) : begin_(NULL), end_(NULL) {}
380         /*! \brief
381          * Constructs a reference to a particular range.
382          *
383          * \param[in] begin  Pointer to the beginning of a range.
384          * \param[in] end    Pointer to the end of a range.
385          *
386          * Passed pointers must remain valid for the lifetime of this object.
387          *
388          * \note For clarity, use the non-member function constArrayRefFromPointers
389          * instead.
390          */
391         ConstArrayRef(const_pointer begin, const_pointer end)
392             : begin_(begin), end_(end)
393         {
394             GMX_ASSERT(end >= begin, "Invalid range");
395         }
396         //! \cond
397         // Doxygen 1.8.5 doesn't parse the declaration correctly...
398         /*! \brief
399          * Constructs a reference to a C array.
400          *
401          * \param[in] array  C array to reference.
402          * \tparam    count  Deduced number of elements in \p array.
403          *
404          * This constructor can only be used with a real array (not with a
405          * pointer).  It constructs a reference to the whole array, without
406          * a need to pass the number of elements explicitly.  The compiler
407          * must be able to deduce the array size.
408          * Passed array must remain valid for the lifetime of this object.
409          *
410          * This constructor is not explicit to allow directly passing
411          * a C array to a function that takes a ConstArrayRef parameter.
412          */
413         template <size_t count>
414         ConstArrayRef(const value_type (&array)[count])
415             : begin_(array), end_(array + count)
416         {
417         }
418         //! \endcond
419
420         //! Returns an iterator to the beginning of the container.
421         const_iterator begin() const { return begin_; }
422         //! Returns an iterator to the end of the container.
423         const_iterator end() const { return end_; }
424         //! Returns an iterator to the reverse beginning of the container.
425         const_iterator rbegin() const { return reverse_iterator(end()); }
426         //! Returns an iterator to the reverse end of the container.
427         const_iterator rend() const { return reverse_iterator(begin()); }
428
429         //! Returns the size of the container.
430         size_type size() const { return end_ - begin_; }
431         //! Identical to size().
432         size_type capacity() const { return end_ - begin_; }
433         //! Whether the container is empty.
434         bool empty() const { return begin_ == end_; }
435
436         //! Access container element.
437         const_reference operator[](size_type n) const { return begin_[n]; }
438         //! Access container element (throws on out-of-range error).
439         const_reference at(size_type n) const
440         {
441             if (n >= size())
442             {
443                 throw std::out_of_range("Vector index out of range");
444             }
445             return begin_[n];
446         }
447         //! Returns the first element in the container.
448         const_reference front() const { return *begin_; }
449         //! Returns the last element in the container.
450         const_reference back() const { return *(end_ - 1); }
451
452         //! Returns a raw pointer to the contents of the array.
453         const_pointer data() const { return begin_; }
454
455         /*! \brief
456          * Swaps referenced memory with the other object.
457          *
458          * The actual memory areas are not modified, only the references are
459          * swapped.
460          */
461         void swap(ConstArrayRef<T> &other)
462         {
463             std::swap(begin_, other.begin_);
464             std::swap(end_, other.end_);
465         }
466
467     private:
468         const_pointer           begin_;
469         const_pointer           end_;
470 };
471
472
473 /*! \brief
474  * Constructs a reference to a particular range from two pointers.
475  *
476  * \param[in] begin  Pointer to the beginning of a range.
477  * \param[in] end    Pointer to the end of a range.
478  *
479  * Passed pointers must remain valid for the lifetime of this object.
480  *
481  * \related ConstArrayRef
482  */
483 template <typename T>
484 ConstArrayRef<T> constArrayRefFromPointers(const T * begin, const T * end)
485 {
486     return ConstArrayRef<T>(begin, end);
487 }
488
489 /*! \brief
490  * Constructs a reference to an array.
491  *
492  * \param[in] begin  Pointer to the beginning of the array.
493  *                   May be NULL if \p size is zero.
494  * \param[in] size   Number of elements in the array.
495  *
496  * Passed pointer must remain valid for the lifetime of this object.
497  *
498  * \related ConstArrayRef
499  */
500 template <typename T>
501 ConstArrayRef<T> constArrayRefFromArray(const T * begin, size_t size)
502 {
503     return constArrayRefFromPointers<T>(begin, begin+size);
504 }
505
506 /*! \brief
507  * Constructs a reference to a particular range in a std::vector.
508  *
509  * \param[in] begin  Iterator to the beginning of a range.
510  * \param[in] end    Iterator to the end of a range.
511  *
512  * The referenced vector must remain valid and not be reallocated for
513  * the lifetime of this object.
514  *
515  * \related ConstArrayRef
516  */
517 template <typename T>
518 ConstArrayRef<T> constArrayRefFromVector(typename std::vector<T>::const_iterator begin,
519                                          typename std::vector<T>::const_iterator end)
520 {
521     const T * p_begin = (begin != end) ? &*begin : NULL;
522     const T * p_end   = p_begin + (end-begin);
523     return constArrayRefFromPointers<T>(p_begin, p_end);
524 }
525
526 /*! \brief
527  * Simple swap method for ArrayRef objects.
528  *
529  * \see ArrayRef::swap()
530  *
531  * \ingroup module_utility
532  */
533 template <typename T>
534 void swap(ArrayRef<T> &a, ArrayRef<T> &b)
535 {
536     a.swap(b);
537 }
538
539 /*! \brief
540  * Simple swap method for ConstArrayRef objects.
541  *
542  * \see ConstArrayRef::swap()
543  *
544  * \ingroup module_utility
545  */
546 template <typename T>
547 void swap(ConstArrayRef<T> &a, ConstArrayRef<T> &b)
548 {
549     a.swap(b);
550 }
551
552 } // namespace gmx
553
554 #endif