ivl 679
ivl/details/core/tool/little_arrayling.hpp
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations