CiftiLib
A C++ library for CIFTI-2 and CIFTI-1 files
MultiDimIterator.h
1#ifndef __MULTI_DIM_ITERATOR_H__
2#define __MULTI_DIM_ITERATOR_H__
3
4/*LICENSE_START*/
5/*
6 * Copyright (c) 2014, Washington University School of Medicine
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without modification,
10 * are permitted provided that the following conditions are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright notice,
16 * this list of conditions and the following disclaimer in the documentation
17 * and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include "stdint.h"
32#include <vector>
33
34namespace cifti
35{
36
37 template<typename T>
39 {
40 std::vector<T> m_dims, m_pos;
41 bool m_atEnd;
42 void gotoBegin();
43 void gotoLast();
44 public:
45 explicit MultiDimIterator(const std::vector<T>& dimensions);
46 void operator++();
47 void operator++(int);
48 void operator--();
49 void operator--(int);
50 const std::vector<T>& operator*() const { return m_pos; }
51 bool atEnd() const { return m_atEnd; }
52 };
53
54 template<typename T>
55 MultiDimIterator<T>::MultiDimIterator(const std::vector<T>& dimensions)
56 {
57 m_dims = dimensions;
58 gotoBegin();
59 }
60
61 template<typename T>
62 void MultiDimIterator<T>::gotoBegin()
63 {
64 m_pos = std::vector<T>(m_dims.size(), 0);
65 m_atEnd = false;
66 size_t numDims = m_dims.size();
67 for (size_t i = 0; i < numDims; ++i)
68 {
69 if (m_dims[i] < 1)
70 {
71 m_atEnd = true;
72 break;
73 }
74 }
75 }
76
77 template<typename T>
78 void MultiDimIterator<T>::gotoLast()
79 {
80 m_pos = std::vector<T>(m_dims.size());
81 m_atEnd = false;
82 size_t numDims = m_dims.size();
83 for (size_t i = 0; i < numDims; ++i)
84 {
85 m_pos[i] = m_dims[i] - 1;
86 if (m_dims[i] < 1)
87 {
88 m_atEnd = true;
89 }
90 }
91 }
92
93 template<typename T>
94 void MultiDimIterator<T>::operator++()
95 {
96 if (atEnd())//wrap around
97 {
98 gotoBegin();
99 return;
100 }
101 if (m_dims.size() == 0)
102 {
103 m_atEnd = true;//special case: no dimensions works the same as 1 dimension of length 1
104 return;
105 }
106 size_t numDims = m_dims.size();
107 for (size_t i = 0; i < numDims; ++i)
108 {
109 ++m_pos[i];
110 if (m_pos[i] < m_dims[i]) return;
111 m_pos[i] = 0;
112 }
113 m_atEnd = true;//if we didn't return already, all of them wrapped, so we are at the end
114 }
115
116 template<typename T>
117 void MultiDimIterator<T>::operator++(int)
118 {
119 ++(*this);
120 }
121
122 template<typename T>
123 void MultiDimIterator<T>::operator--()
124 {
125 if (atEnd())//wrap around
126 {
127 gotoLast();
128 return;
129 }
130 if (m_dims.size() == 0)
131 {
132 m_atEnd = true;//special case: no dimensions works the same as 1 dimension of length 1
133 return;
134 }
135 size_t numDims = m_dims.size();
136 for (size_t i = 0; i < numDims; ++i)
137 {
138 if (m_pos[i] > 0)
139 {
140 --m_pos[i];
141 return;
142 } else {
143 m_pos[i] = m_dims[i] - 1;
144 }
145 }
146 m_atEnd = true;//if we didn't return already, all of them wrapped, so we are at the end
147 }
148
149 template<typename T>
150 void MultiDimIterator<T>::operator--(int)
151 {
152 --(*this);
153 }
154
155}
156
157#endif //__MULTI_DIM_ITERATOR_H__
Definition: MultiDimIterator.h:39
namespace for all CiftiLib functionality
Definition: CiftiBrainModelsMap.h:42