ivl 679
|
00001 /* This file is part of the ivl C++ library <http://image.ntua.gr/ivl>. 00002 A C++ template library extending syntax towards mathematical notation. 00003 00004 Copyright (C) 2012 Yannis Avrithis <iavr@image.ntua.gr> 00005 Copyright (C) 2012 Kimon Kontosis <kimonas@image.ntua.gr> 00006 00007 ivl is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU Lesser General Public License 00009 version 3 as published by the Free Software Foundation. 00010 00011 Alternatively, you can redistribute it and/or modify it under the terms 00012 of the GNU General Public License version 2 as published by the Free 00013 Software Foundation. 00014 00015 ivl is distributed in the hope that it will be useful, 00016 but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00018 See the GNU General Public License for more details. 00019 00020 You should have received a copy of the GNU General Public License 00021 and a copy of the GNU Lesser General Public License along 00022 with ivl. If not, see <http://www.gnu.org/licenses/>. */ 00023 00024 #ifndef IVL_CORE_DETAILS_TOOL_LITTLE_ARRAYLING_HPP 00025 #define IVL_CORE_DETAILS_TOOL_LITTLE_ARRAYLING_HPP 00026 00027 /* 00028 * Description: 00029 * 00030 * ivl contains a type array<T, data::little<N> > with pre-allocated memory 00031 * for N cells in the struct itself, as a normal C array. 00032 * this array can have any variable length, however if the length is less 00033 * or equal to N, the local storage is used avoiding the malloc overhead. 00034 * 00035 * This kind of array is useful also in some low-level parts of the 00036 * implementation of ivl, like the subarray iterator. 00037 * 00038 * In order to avoid a bad design we want to avoid using the actual 00039 * array struct in a such low-level part of the library. This 00040 * would yield complicated and unjustified #includes and forward 00041 * declarations. So we rewrite a very simple array called little_arrayling. 00042 * - it is named little after the data type that uses N cells. 00043 * This class implements only the very basic functionality that is needed. 00044 * 00045 * The reason this class is used over the stl vector is the possible 00046 * speed-up that it offers when used to store small data. 00047 * 00048 */ 00049 00050 namespace ivl { 00051 namespace internal { 00052 00053 template <class T, int N = 4> 00054 class little_arrayling 00055 { 00056 private: 00057 size_t len; 00058 T* ptr; 00059 T data[N]; 00060 00061 void _setsize(size_t x) { if(x > N) ptr = new T[x]; len = x; } 00062 void _resetsize(size_t x) { 00063 if(len == x) return; 00064 if(len > N) delete[] ptr; ptr = data; _setsize(x); 00065 } 00066 00067 template<class A> 00068 void _copy_from(const A& ar) 00069 { 00070 T* dst = ptr; 00071 for(typename A::const_iterator it = ar.begin(); it != ar.end(); it++) 00072 *dst++ = *it++; 00073 } 00074 void _copy_from_ptr(const T* p, const T* p_end) 00075 { 00076 T* dst = ptr; 00077 while(p != p_end) *(dst++) = *(p++); 00078 } 00079 00080 public: 00081 little_arrayling() { ptr = data; len = 0; }; // should call setsize 00082 00083 little_arrayling(size_t sz) { ptr = data; _setsize(sz); }; 00084 00085 little_arrayling(const little_arrayling& ar) 00086 { ptr = data; _setsize(ar.len); _copy_from_ptr(ar.ptr, ar.ptr + len); } 00087 00088 template<class A> 00089 little_arrayling(A& ar) 00090 { ptr = data; _setsize(ar.length()); _copy_from(ar); } 00091 00092 ~little_arrayling() { if(len > N) delete[] ptr; } 00093 00094 little_arrayling& operator=(const little_arrayling& o) 00095 { _resetsize(o.len); _copy_from_ptr(o.ptr, o.ptr + len); return *this; } 00096 00097 void setsize(size_t sz) { _setsize(sz); } // should only be called once 00098 00099 template<class A> 00100 void copy_from(const A& ar) { _copy_from(ar); } 00101 00102 T& operator[](size_t x) { return ptr[x]; } 00103 00104 const T& operator[](size_t x) const { return ptr[x]; } 00105 00106 size_t length() const { return len; } 00107 00108 T* c_ptr() { return ptr; } 00109 00110 const T* c_ptr() const { return ptr; } 00111 }; 00112 00113 } /* namespace internal */ 00114 } /* namespace ivl */ 00115 00116 #endif // IVL_CORE_DETAILS_TOOL_LITTLE_ARRAYLING_HPP