Sirikata
|
00001 /* Sirikata Utilities -- Sirikata Synchronization Utilities 00002 * Array.hpp 00003 * 00004 * Copyright (c) 2009, Daniel Reiter Horn 00005 * All rights reserved. 00006 * 00007 * Redistribution and use in source and binary forms, with or without 00008 * modification, are permitted provided that the following conditions are 00009 * met: 00010 * * Redistributions of source code must retain the above copyright 00011 * notice, this list of conditions and the following disclaimer. 00012 * * Redistributions in binary form must reproduce the above copyright 00013 * notice, this list of conditions and the following disclaimer in 00014 * the documentation and/or other materials provided with the 00015 * distribution. 00016 * * Neither the name of Sirikata nor the names of its contributors may 00017 * be used to endorse or promote products derived from this software 00018 * without specific prior written permission. 00019 * 00020 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 00021 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 00022 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 00023 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 00024 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00025 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00026 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00027 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00028 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00029 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00030 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00031 */ 00032 00033 #ifndef _SIRIKATA_ARRAY_HPP_ 00034 #define _SIRIKATA_ARRAY_HPP_ 00035 00036 #include <cstddef> 00037 #include <stdexcept> 00038 00039 namespace Sirikata { 00040 template <class T, std::size_t N, bool integral_type=true> class Array { 00041 public: 00042 enum {static_size=N}; 00043 static std::size_t size() {return N;} 00044 private: 00045 T mElems[static_size]; 00046 public: 00047 typedef T value_type; 00048 typedef T* iterator; 00049 typedef const T* const_iterator; 00050 typedef T& reference; 00051 typedef const T& const_reference; 00052 typedef std::size_t size_type; 00053 typedef std::ptrdiff_t difference_type; 00054 template <typename InputIterator> Array* initialize(InputIterator begin, 00055 InputIterator end) { 00056 std::size_t i=0; 00057 for (;i<N&&begin!=end; ++begin,++i) { 00058 mElems[i]=*begin; 00059 } 00060 if (i!=static_size) { 00061 throw std::invalid_argument("Array<> constructor not passed valid number of input arguments"); 00062 } 00063 return this; 00064 } 00065 Array* memcpy(const void *input, std::size_t len) { 00066 if (len==(static_size*sizeof(T))) { 00067 for (std::size_t i=0;i<N;++i) { 00068 mElems[i]=((T*)input)[i]; 00069 } 00070 }else { 00071 throw std::invalid_argument("Array<> constructor not passed valid length of input memory"); 00072 } 00073 return this; 00074 } 00075 iterator begin() { return mElems; } 00076 const_iterator begin() const { return mElems; } 00077 iterator end() { return mElems+static_size; } 00078 const_iterator end() const { return mElems+static_size; } 00079 reference operator[](size_type i) { 00080 return mElems[i]; 00081 } 00082 const_reference operator[](size_type i) const { 00083 return mElems[i]; 00084 } 00085 reference front() { 00086 return mElems[0]; 00087 } 00088 const_reference front() const { 00089 return mElems[0]; 00090 } 00091 reference back() { 00092 return mElems[static_size-1]; 00093 } 00094 const_reference back() const { 00095 return mElems[static_size-1]; 00096 } 00097 const T* data() const { return mElems; } 00098 T* data() { return mElems; } 00099 static const Array& null() { 00100 static Array nix; 00101 static unsigned char nothing[static_size*sizeof(T)]={0}; 00102 static Array nulle=*nix.memcpy(nothing,static_size); 00103 return nulle; 00104 } 00105 template <class InputIterator> static Array construct(InputIterator begin, 00106 InputIterator end) { 00107 Array retval; 00108 retval.initialize(begin,end); 00109 return retval; 00110 } 00111 template <class InputIterator> static Array construct(InputIterator begin) { 00112 Array retval; 00113 retval.initialize(begin,begin+static_size); 00114 return retval; 00115 } 00116 bool operator <(const Array &other)const { 00117 if (integral_type) { 00118 return std::memcmp(mElems,other.mElems,static_size*sizeof(T))<0; 00119 }else { 00120 for (size_t i=0;i<static_size;++i) { 00121 if (mElems[i]<other.mElems[i]) return true; 00122 if (!(mElems[i]==other.mElems[i])) return false; 00123 } 00124 return false; 00125 } 00126 } 00127 bool operator ==(const Array &other)const { 00128 if (integral_type) { 00129 return std::memcmp(mElems,other.mElems,static_size*sizeof(T))==0; 00130 }else { 00131 for (size_t i=0;i<static_size;++i) { 00132 if (!(mElems[i]==other.mElems[i])) return false; 00133 } 00134 return true; 00135 } 00136 } 00137 bool operator !=(const Array &other)const { 00138 return !(*this==other); 00139 } 00140 }; 00141 00142 } 00143 00144 #endif //_SIRIKATA_ARRAY_HPP_