osgEarth 2.1.1
|
00001 /* -*-c++-*- */ 00002 /* osgEarth - Dynamic map generation toolkit for OpenSceneGraph 00003 * Copyright 2008-2009 Pelican Ventures, Inc. 00004 * http://osgearth.org 00005 * 00006 * osgEarth is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU Lesser General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public License 00017 * along with this program. If not, see <http://www.gnu.org/licenses/> 00018 */ 00019 00020 // Poor man's multi array adapter. 00021 00022 #ifndef SEAMLESS_MULTIARRAY 00023 #define SEAMLESS_MULTIARRAY 1 00024 00025 #include <algorithm> 00026 00027 namespace seamless 00028 { 00029 00030 template<typename ElementType, typename Store, unsigned N> class Reference; 00031 00032 template<typename ElementType, typename Store, unsigned N> 00033 class SubArraySimple : public Reference<ElementType, Store, N> 00034 { 00035 public: 00036 typedef Reference<ElementType, Store, N> super_type; 00037 typedef typename super_type::reference reference; 00038 SubArraySimple(int base, Store& store, const int* strides) 00039 : super_type(base), _store(store), _strides(strides) 00040 { 00041 } 00042 00043 SubArraySimple(const SubArraySimple& rhs); 00044 00045 reference operator[](int index) 00046 { 00047 return super_type::access(index, _store, _strides); 00048 } 00049 protected: 00050 Store& _store; 00051 const int* _strides; 00052 }; 00053 00054 template<typename ElementType, typename Store, unsigned N> 00055 class SubArray : public SubArraySimple<ElementType, Store, N> 00056 { 00057 typedef SubArraySimple<ElementType, Store, N> super_type; 00058 typedef typename super_type::reference reference; 00059 public: 00060 SubArray(int base, Store& store, 00061 const int* strides, const int* indexBase) 00062 : super_type(base, store, strides), _indexBase(indexBase) 00063 { 00064 } 00065 00066 SubArray(const SubArray& rhs) 00067 : super_type(rhs), _indexBase(rhs._indexBase) 00068 { 00069 } 00070 00071 reference operator[](int index) 00072 { 00073 return super_type::access(index, this->_store, this->_strides, 00074 _indexBase); 00075 } 00076 protected: 00077 const int* _indexBase; 00078 }; 00079 00080 00081 template<typename ElementType, typename Store, unsigned N> 00082 class Reference 00083 { 00084 public: 00085 typedef SubArraySimple<ElementType, Store, N - 1> simple_reference; 00086 typedef SubArray<ElementType, Store, N - 1> reference; 00087 Reference(int base) : _base(base) {} 00088 00089 Reference(const Reference& rhs) : _base(rhs._base) {} 00090 00091 simple_reference access(int index, Store& store, const int* strides) const 00092 { 00093 int newbase = _base + index * strides[0]; 00094 return simple_reference(newbase, store, strides + 1); 00095 } 00096 00097 reference access(int index, Store& store, const int* strides, 00098 const int* indexBase) const 00099 { 00100 int newbase = _base + (index - indexBase[0]) * strides[0]; 00101 return reference(newbase, store, indexBase + 1, strides + 1); 00102 } 00103 const int _base; 00104 }; 00105 00106 template<typename ElementType, typename Store> 00107 class Reference<ElementType, Store, 1> 00108 { 00109 public: 00110 Reference(int base) : _base(base) {} 00111 Reference(const Reference& rhs) : _base(rhs._base) {} 00112 00113 typedef ElementType& simple_reference; 00114 typedef ElementType& reference; 00115 00116 simple_reference access(int index, Store& store, const int* strides) 00117 { 00118 return store[_base + index * strides[0]]; 00119 } 00120 00121 reference access(int index, Store& store, const int* strides, 00122 const int* indexBase) 00123 { 00124 return store[_base + (index - indexBase[0]) * strides[0]]; 00125 } 00126 00127 const int _base; 00128 }; 00129 00130 template<typename ElementType, typename Store, unsigned N> 00131 inline SubArraySimple<ElementType, Store, N>::SubArraySimple( 00132 const SubArraySimple& rhs) 00133 : super_type(rhs), _store(rhs._store), _strides(rhs._strides) 00134 { 00135 } 00136 00137 template<typename ElementType, typename Store, unsigned N> 00138 class multi_array_ref : public Reference<ElementType, Store, N> 00139 { 00140 public: 00141 typedef Reference<ElementType, Store, N> super_type; 00142 typedef typename super_type::simple_reference simple_reference; 00143 multi_array_ref(Store& store, unsigned dimension, int base = 0) 00144 : _store(store), super_type(base) 00145 { 00146 std::fill_n(&_shape[0], N, dimension); 00147 std::fill_n(&_indexBase[0], N, 0); 00148 _strides[N - 1] = 1; 00149 for (int i = N - 2; i >= 0; --i) 00150 { 00151 _strides[i] = dimension * _strides[i + 1]; 00152 } 00153 } 00154 00155 multi_array_ref(Store& store, int *strides, int *shape, int base) 00156 : _store(store), super_type(base) 00157 { 00158 std::copy(&shape[0], &shape[N], &_shape[0]); 00159 std::fill_n(&_indexBase[0], N, 0); 00160 std::copy(&strides[0], &strides[N], &_strides[0]); 00161 00162 } 00163 00164 multi_array_ref(const multi_array_ref& rhs) 00165 : super_type(rhs), _store(rhs._store) 00166 { 00167 std::copy(&rhs._shape[0], &rhs._shape[N], &_shape[0]); 00168 std::copy(&rhs._indexBase[0], &rhs._indexBase[N], &_indexBase[0]); 00169 std::copy(&rhs._strides[0], &rhs._strides[N], &_strides[0]); 00170 } 00171 00172 simple_reference operator[](int index) 00173 { 00174 return super_type::access(index, _store, _strides); 00175 } 00176 00177 int shape(int n) const { return _shape[n]; } 00178 int indexBase(int n) const { return _indexBase[n]; } 00179 int stride(int n) const { return _strides[n]; } 00180 protected: 00181 Store& _store; 00182 int _shape[N]; 00183 int _indexBase[N]; 00184 int _strides[N]; 00185 }; 00186 00187 template<typename ElementType, typename Store> 00188 class vector_ref : public multi_array_ref<ElementType, Store, 1> 00189 { 00190 public: 00191 typedef multi_array_ref<ElementType, Store, 1> super_type; 00192 00193 vector_ref(Store& store, int stride, int shape, int base) 00194 : super_type(store, &stride, &shape, base) 00195 { 00196 } 00197 00198 int shape() const { return super_type::shape(0); } 00199 }; 00200 00201 } 00202 #endif