Implement common analysis data value object.
[alexxy/gromacs.git] / src / gromacs / utility / arrayref.h
1 /*
2  *
3  *                This source code is part of
4  *
5  *                 G   R   O   M   A   C   S
6  *
7  *          GROningen MAchine for Chemical Simulations
8  *
9  * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
10  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
11  * Copyright (c) 2001-2009, The GROMACS development team,
12  * check out http://www.gromacs.org for more information.
13  *
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  *
19  * If you want to redistribute modifications, please consider that
20  * scientific software is very special. Version control is crucial -
21  * bugs must be traceable. We will be happy to consider code for
22  * inclusion in the official distribution, but derived work must not
23  * be called official GROMACS. Details are found in the README & COPYING
24  * files - if they are missing, get the official version at www.gromacs.org.
25  *
26  * To help us fund GROMACS development, we humbly ask that you cite
27  * the papers on the package - you can find them in the top README file.
28  *
29  * For more info, check our website at http://www.gromacs.org
30  */
31 /*! \file
32  * \brief
33  * Declares gmx::ConstArrayRef.
34  *
35  * \author Teemu Murtola <teemu.murtola@cbr.su.se>
36  * \inpublicapi
37  * \ingroup module_utility
38  */
39 #ifndef GMX_UTILITY_ARRAYREF_H
40 #define GMX_UTILITY_ARRAYREF_H
41
42 #include <cstddef>
43
44 #include <iterator>
45 #include <stdexcept>
46 #include <utility>
47 #include <vector>
48
49 #include "../fatalerror/gmxassert.h"
50
51 namespace gmx
52 {
53
54 /*! \brief
55  * STL container non-mutable interface for a C array (or part of a std::vector).
56  *
57  * \tparam T  Value type of elements.
58  *
59  * This class provides an interface similar to \c std::vector<T>, with the
60  * following main differences:
61  *  - This class does not have its own storage.  Instead, it references an
62  *    existing array of values (either a C-style array or part of an existing
63  *    std::vector<T>).
64  *  - Only const methods are provided to access the stored values.
65  *    It is not possible to alter the referenced array.
66  *  - Copying objects of this type is cheap, and the copies behave identically
67  *    to the original object: the copy references the same set of values.
68  *
69  * \inpublicapi
70  * \ingroup module_utility
71  */
72 template <typename T>
73 class ConstArrayRef
74 {
75     public:
76         typedef T         value_type;
77         typedef size_t    size_type;
78         typedef ptrdiff_t difference_type;
79         typedef const T  &const_reference;
80         typedef const T  *const_pointer;
81         typedef const T  *const_iterator;
82         //! Equal to \a const_reference since changes are not allowed.
83         typedef const_reference reference;
84         //! Equal to \a const_pointer since changes are not allowed.
85         typedef const_pointer   pointer;
86         //! Equal to \a const_iterator since changes are not allowed.
87         typedef const_iterator  iterator;
88         //! Standard reverse iterator.
89         typedef std::reverse_iterator<iterator>       reverse_iterator;
90         //! Standard reverse iterator.
91         typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
92
93         /*! \brief
94          * Constructs an empty reference.
95          */
96         ConstArrayRef() : begin_(NULL), end_(NULL) {}
97         /*! \brief
98          * Constructs a reference to a particular range.
99          *
100          * \param[in] begin  Pointer to the beginning of a range.
101          * \param[in] end    Pointer to the end of a range.
102          *
103          * Passed pointers must remain valid for the lifetime of this object.
104          */
105         ConstArrayRef(const_pointer begin, const_pointer end)
106             : begin_(begin), end_(end)
107         {
108             GMX_ASSERT(end >= begin, "Invalid range");
109         }
110         /*! \brief
111          * Constructs a reference to a particular rangein a std::vector.
112          *
113          * \param[in] begin  Pointer to the beginning of a range.
114          * \param[in] end    Pointer to the end of a range.
115          *
116          * The referenced vector must remain valid and not be reallocated for
117          * the lifetime of this object.
118          */
119         ConstArrayRef(typename std::vector<T>::const_iterator begin,
120                       typename std::vector<T>::const_iterator end)
121             : begin_((begin != end) ? &*begin : NULL),
122               end_((begin != end) ? &*end : NULL)
123         {
124             GMX_ASSERT(end >= begin, "Invalid range");
125         }
126         /*! \brief
127          * Constructs a reference to an array.
128          *
129          * \param[in] size   Number of elements in the array.
130          * \param[in] begin  Pointer to the beginning of the array.
131          *      May be NULL if \p size is zero.
132          *
133          * Passed pointer must remain valid for the lifetime of this object.
134          */
135         ConstArrayRef(size_type size, const_pointer begin)
136             : begin_(begin), end_(begin + size)
137         {
138         }
139
140         const_iterator begin() const { return begin_; }
141         const_iterator end() const { return end_; }
142         const_iterator rbegin() const { return reverse_iterator(end()); }
143         const_iterator rend() const { return reverse_iterator(begin()); }
144
145         size_type size() const { return end_ - begin_; }
146         size_type capacity() const { return end_ - begin_; }
147         bool empty() const { return begin_ == end_; }
148
149         const_reference operator[](size_type n) const { return begin_[n]; }
150         const_reference at(size_type n) const
151         {
152             if (n >= size())
153             {
154                 throw std::out_of_range("Vector index out of range");
155             }
156             return begin_[n];
157         }
158         const_reference front() const { return *begin_; }
159         const_reference back() const { return *(end_ - 1); }
160
161         /*! \brief
162          * Swaps referenced memory with the other object.
163          *
164          * The actual memory areas are not modified, only the references are
165          * swapped.
166          */
167         void swap(ConstArrayRef<T> &other)
168         {
169             std::swap(begin_, other.begin_);
170             std::swap(end_, other.end_);
171         }
172
173     private:
174         const_pointer           begin_;
175         const_pointer           end_;
176 };
177
178 /*! \brief
179  * Simple swap method for ConstArrayRef objects.
180  *
181  * \see ConstArrayRef::swap()
182  */
183 template <typename T>
184 void swap(ConstArrayRef<T> &a, ConstArrayRef<T> &b)
185 {
186     a.swap(b);
187 }
188
189 } // namespace gmx
190
191 #endif