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 
34 namespace 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