CiftiLib
A C++ library for CIFTI-2 and CIFTI-1 files
MultiDimArray.h
1 #ifndef __MULTI_DIM_ARRAY_H__
2 #define __MULTI_DIM_ARRAY_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 "CiftiAssert.h"
32 
33 #include "stdint.h"
34 #include <vector>
35 
36 namespace cifti
37 {
38 
39  template<typename T>
41  {
42  std::vector<int64_t> m_dims, m_skip;//always use int64_t for indexes internally
43  std::vector<T> m_data;
44  template<typename I>
45  int64_t index(const int& fullDims, const std::vector<I>& indexSelect) const;//assume we never need over 2 billion dimensions
46  public:
47  const std::vector<int64_t>& getDimensions() const { return m_dims; }
48  template<typename I>
49  void resize(const std::vector<I>& dims);//destructive resize
50  template<typename I>
51  T& at(const std::vector<I>& pos);
52  template<typename I>
53  const T& at(const std::vector<I>& pos) const;
54  template<typename I>
55  T* get(const int& fullDims, const std::vector<I>& indexSelect);//subarray reference selection
56  template<typename I>
57  const T* get(const int& fullDims, const std::vector<I>& indexSelect) const;
58  };
59 
60  template<typename T>
61  template<typename I>
62  void MultiDimArray<T>::resize(const std::vector<I>& dims)
63  {
64  m_dims = std::vector<int64_t>(dims.begin(), dims.end());
65  m_skip.resize(m_dims.size());
66  if (dims.size() == 0)
67  {
68  m_data.clear();
69  return;
70  }
71  int64_t numElems = 1;
72  for (int i = 0; i < (int)m_dims.size(); ++i)
73  {
74  CiftiAssert(m_dims[i] > 0);
75  m_skip[i] = numElems;
76  numElems *= m_dims[i];
77  }
78  m_data.resize(numElems);
79  }
80 
81  template<typename T>
82  template<typename I>
83  int64_t MultiDimArray<T>::index(const int& fullDims, const std::vector<I>& indexSelect) const
84  {
85  CiftiAssert(fullDims + indexSelect.size() == m_dims.size());
86  int64_t ret = 0;
87  for (int i = fullDims; i < (int)m_dims.size(); ++i)
88  {
89  CiftiAssert(indexSelect[i - fullDims] >= 0 && indexSelect[i - fullDims] < m_dims[i]);
90  ret += m_skip[i] * indexSelect[i - fullDims];
91  }
92  return ret;
93  }
94 
95  template<typename T>
96  template<typename I>
97  T& MultiDimArray<T>::at(const std::vector<I>& pos)
98  {
99  return m_data[index(0, pos)];
100  }
101 
102  template<typename T>
103  template<typename I>
104  const T& MultiDimArray<T>::at(const std::vector<I>& pos) const
105  {
106  return m_data[index(0, pos)];
107  }
108 
109  template<typename T>
110  template<typename I>
111  T* MultiDimArray<T>::get(const int& fullDims, const std::vector<I>& indexSelect)
112  {
113  return m_data.data() + index(fullDims, indexSelect);
114  }
115 
116  template<typename T>
117  template<typename I>
118  const T* MultiDimArray<T>::get(const int& fullDims, const std::vector<I>& indexSelect) const
119  {
120  return m_data.data() + index(fullDims, indexSelect);
121  }
122 }
123 
124 #endif //__MULTI_DIM_ARRAY_H__
cifti::MultiDimArray
Definition: MultiDimArray.h:40
cifti
namespace for all CiftiLib functionality
Definition: CiftiBrainModelsMap.h:41