Simple Application Framework  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Saf/Collection/StaticArray.h
Go to the documentation of this file.
00001 /*
00002     This file is part of Simple Application Framework (Saf) library.
00003     Copyright (C) 2010 - 2012 Ondrej Danek <ondrej.danek@gmail.com>
00004 
00005     This library is free software: you can redistribute it and/or modify
00006     it under the terms of the GNU General Public License as published 
00007     by the Free Software Foundation, either version 3 of the License, or
00008     (at your option) any later version.
00009 
00010     Saf is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013     GNU General Public License for more details.
00014 
00015     You should have received a copy of the GNU General Public License
00016     along with Simple Application Framework library. If not, 
00017     see <http://www.gnu.org/licenses/>.
00018 */
00019 
00028 #ifndef SAF_COLLECTION_STATICARRAY_H
00029 #define SAF_COLLECTION_STATICARRAY_H
00030 
00031 #include "../Type.h"
00032 #include "../InvalidOperationException.h"
00033 #include "../Algo/Range.h"
00034 
00035 namespace Saf
00036 {
00038     namespace Collection
00039     {
00049         template <Size N, class T>
00050         class StaticArray
00051         {
00052         protected:
00053             typedef StaticArray<N,T> MyType;
00054 
00055         public:
00056             typedef T* Iterator;
00057             typedef const T* ConstIterator;
00058 
00059         protected: 
00061             T m_data[N];
00062 
00063         public:
00068             StaticArray()
00069             {}
00070 
00075             explicit StaticArray(const T& val)
00076             {
00077                 // Compiler will optimize this out 
00078                 if (N == 1)
00079                 {
00080                     *m_data = val;
00081                 }
00082                 else if (N == 2)
00083                 {
00084                     m_data[0] = val;
00085                     m_data[1] = val;
00086                 }
00087                 else if (N == 3)
00088                 {
00089                     m_data[0] = val;
00090                     m_data[1] = val;
00091                     m_data[2] = val;
00092                 }
00093                 else if (N == 4)
00094                 {
00095                     m_data[0] = val;
00096                     m_data[1] = val;
00097                     m_data[2] = val;
00098                     m_data[3] = val;
00099                 }
00100                 else
00101                 {
00102                     Algo::Range::Fill(Begin(), End(), val);
00103                 }
00104             }
00105 
00107             StaticArray(const T& v1, const T& v2)
00108             {
00109                 Set(v1, v2);
00110             }
00111 
00113             StaticArray(const T& v1, const T& v2, const T& v3)
00114             {
00115                 Set(v1, v2, v3);
00116             }
00117 
00119             StaticArray(const T& v1, const T& v2, const T& v3, const T& v4)
00120             {
00121                 Set(v1, v2, v3, v4);
00122             }
00123 
00125             StaticArray(const MyType& t)
00126             {
00127                 *this = t;
00128             }
00129 
00131             MyType& operator=(const MyType& t)
00132             {
00133                 // Compiler will optimize this out
00134                 if (N == 1)
00135                 {
00136                     *m_data = *t.m_data;
00137                 }
00138                 else if (N == 2)
00139                 {
00140                     m_data[0] = t.m_data[0];
00141                     m_data[1] = t.m_data[1];
00142                 }
00143                 else if (N == 3)
00144                 {
00145                     m_data[0] = t.m_data[0];
00146                     m_data[1] = t.m_data[1];
00147                     m_data[2] = t.m_data[2];
00148                 }
00149                 else if (N == 4)
00150                 {
00151                     m_data[0] = t.m_data[0];
00152                     m_data[1] = t.m_data[1];
00153                     m_data[2] = t.m_data[2];
00154                     m_data[3] = t.m_data[3];
00155                 }
00156                 else
00157                 {
00158                     Algo::Range::Copy(t.Begin(), t.End(), Begin());
00159                 }
00160 
00161                 return *this;
00162             }
00163 
00165             Size Elements() const
00166             {
00167                 return N;
00168             }
00169 
00171             const T& operator[](Size i) const
00172             {
00173                 return m_data[i];
00174             }
00175 
00177             T& operator[](Size i)
00178             {
00179                 return m_data[i];
00180             }
00181 
00183             Iterator Begin()
00184             {
00185                 return m_data;
00186             }
00187 
00189             ConstIterator Begin() const
00190             {
00191                 return m_data;
00192             }
00193 
00195             Iterator End()
00196             {
00197                 return m_data + N;
00198             }
00199 
00201             ConstIterator End() const
00202             {
00203                 return m_data + N;
00204             }
00205 
00207             Iterator Front()
00208             {
00209                 return m_data;
00210             }
00211 
00213             ConstIterator Front() const
00214             {
00215                 return m_data;
00216             }
00217 
00219             Iterator Back()
00220             {
00221                 return m_data + (N - 1);
00222             }
00223 
00225             ConstIterator Back() const
00226             {
00227                 return m_data + (N - 1);
00228             }
00229 
00234             MyType& Set(const T& v1, const T& v2)
00235             {
00236                 if (N != 2)
00237                 {
00238                     throw InvalidOperationException(SAF_SOURCE_LOCATION, "Method applicable"
00239                         " to arrays of size 2 only.");
00240                 }
00241                 else
00242                 {
00243                     m_data[0] = v1;
00244                     m_data[1] = v2;
00245                 }
00246 
00247                 return *this;
00248             }
00249 
00254             MyType& Set(const T& v1, const T& v2, const T& v3)
00255             {
00256                 if (N != 3)
00257                 {
00258                     throw InvalidOperationException(SAF_SOURCE_LOCATION, "Method applicable"
00259                         " to arrays of size 2 only.");
00260                 }
00261                 else
00262                 {
00263                     m_data[0] = v1;
00264                     m_data[1] = v2;
00265                     m_data[2] = v3;
00266                 }
00267 
00268                 return *this;
00269             }
00270 
00275             MyType& Set(const T& v1, const T& v2, const T& v3, const T& v4)
00276             {
00277                 if (N != 4)
00278                 {
00279                     throw InvalidOperationException(SAF_SOURCE_LOCATION, "Method applicable"
00280                         " to arrays of size 2 only.");
00281                 }
00282                 else
00283                 {
00284                     m_data[0] = v1;
00285                     m_data[1] = v2;
00286                     m_data[2] = v3;
00287                     m_data[3] = v4;
00288                 }
00289 
00290                 return *this;
00291             }
00292 
00294             bool operator==(const MyType& t) const
00295             {
00296                 // Compiler will optimize this out
00297                 if (N == 1)
00298                 {
00299                     return (*m_data == *t.m_data);
00300                 }
00301                 else if (N == 2)
00302                 {
00303                     return (m_data[0] == t.m_data[0] && m_data[1] == t.m_data[1]);
00304                 }
00305                 else if (N == 3)
00306                 {
00307                     return (m_data[0] == t.m_data[0] && m_data[1] == t.m_data[1] &&
00308                         m_data[2] == t.m_data[2]);
00309                 }
00310                 else if (N == 4)
00311                 {
00312                     return (m_data[0] == t.m_data[0] && m_data[1] == t.m_data[1] &&
00313                         m_data[2] == t.m_data[2] && m_data[3] == t.m_data[3]);
00314                 }
00315 
00316                 return Algo::Range::Equal(Begin(), End(), t.Begin());
00317             }
00318 
00320             bool operator!=(const MyType& t) const
00321             {
00322                 return !(*this == t);
00323             }
00324         };
00325     }
00326 }
00327 
00328 #endif