00001 // Torc - Copyright 2011 University of Southern California. All Rights Reserved. 00002 // $HeadURL: https://svn.east.isi.edu/torc/trunk/src/torc/architecture/Array.hpp $ 00003 // $Id: Array.hpp 450 2011-04-29 18:47:50Z nsteiner $ 00004 00005 // This program is free software: you can redistribute it and/or modify it under the terms of the 00006 // GNU General Public License as published by the Free Software Foundation, either version 3 of the 00007 // License, or (at your option) any later version. 00008 // 00009 // This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 00010 // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 00011 // the GNU General Public License for more details. 00012 // 00013 // You should have received a copy of the GNU General Public License along with this program. If 00014 // not, see <http://www.gnu.org/licenses/>. 00015 00016 /// \file 00017 /// \brief Header for the Array class. 00018 00019 #ifndef TORC_ARCHITECTURE_ARRAY_HPP 00020 #define TORC_ARCHITECTURE_ARRAY_HPP 00021 00022 #include <boost/cstdint.hpp> 00023 #include <boost/type_traits.hpp> 00024 #include <stdexcept> 00025 #include <cstdio> 00026 00027 namespace torc { 00028 namespace architecture { 00029 00030 /// \brief Encapsulation of a static array. 00031 /// \details Arrays are intended for fixed-size operation without frills, and are used 00032 /// extensively to represent device wiring data. Although this class could be used more 00033 /// broadly, it is likely that most code would be better served by raw arrays or by STL 00034 /// containers. 00035 /// <p> 00036 /// Arrays can be resized, but their contents are not retained when resized, nor are the 00037 /// contents cleared upon initialization. 00038 template <class T> class Array { 00039 protected: 00040 // types 00041 /// \brief Imported type name. 00042 typedef boost::uint32_t uint32_t; 00043 /// \brief A type identical to template parameter T, but with any 'const' trait removed. 00044 typedef typename boost::remove_const<T>::type T_non_const; 00045 // members 00046 /// \brief The internal array. 00047 T* mArray; 00048 /// \brief The logical and actual size of the array. 00049 uint32_t mSize; 00050 private: 00051 /// \brief Allocate an array of the specified size. 00052 void allocate(uint32_t inSize) { 00053 if(mArray != 0) deallocate(); 00054 if(inSize > 0) { 00055 // T might be a const type, so we get Boost to remove the const trait 00056 mArray = new T_non_const[inSize]; 00057 mSize = inSize; 00058 } 00059 } 00060 /// \brief Deallocate the array. 00061 void deallocate(void) { 00062 if(mArray != 0) delete[] mArray; 00063 mArray = 0; 00064 mSize = 0; 00065 } 00066 #ifdef DEBUG 00067 /// \brief Enforce array bounds if so requested. 00068 #define enforceBounds(index) \ 00069 if(index >= mSize || index < 0) { \ 00070 char scratch[1 << 10]; \ 00071 snprintf(scratch, sizeof(scratch), "Index %d not in valid range [0,%d).", index, \ 00072 mSize); \ 00073 throw std::out_of_range(scratch); \ 00074 } 00075 #else 00076 /// \brief Enforce array bounds if so requested. 00077 #define enforceBounds(index) ; 00078 #endif 00079 public: 00080 // types 00081 /// \brief Constant T iterator type. 00082 typedef const T* const_iterator; 00083 /// \brief Non-constant T iterator type. 00084 typedef T* iterator; 00085 // constructors 00086 /// \brief Null constructor. 00087 Array<T>(void) : mArray(0), mSize(0) {} 00088 /// \brief Public constructor. 00089 Array<T>(uint32_t inSize) : mArray(0), mSize(0) { allocate(inSize); } 00090 /// \brief Non-virtual destructor. 00091 ~Array<T>(void) { deallocate(); } 00092 // iterators 00093 /// \brief Returns the non-constant begin iterator. 00094 T* begin(void) { return mArray; } 00095 /// \brief Returns the non-constant end iterator. 00096 T* end(void) { return mArray + mSize; } 00097 /// \brief Returns the constant begin iterator. 00098 const T* begin(void) const { return mArray; } 00099 /// \brief Returns the constant end iterator. 00100 const T* end(void) const { return mArray + mSize; } 00101 // accessors 00102 /// \brief Returns the array size. 00103 inline uint32_t getSize(void) const { return mSize; } 00104 // functions 00105 /// \brief Discards all contents and resizes the array. 00106 inline void setSize(uint32_t inSize) { allocate(inSize); } 00107 // operators 00108 /// \brief Non-constant subscript operator. 00109 T& operator [](uint32_t inIndex) { 00110 enforceBounds(inIndex); 00111 return mArray[inIndex]; 00112 } 00113 /// \brief Constant subscript operator. 00114 const T& operator [](uint32_t inIndex) const { 00115 enforceBounds(inIndex); 00116 return mArray[inIndex]; 00117 } 00118 }; 00119 00120 /// \brief Encapsulation of a 2D static array. 00121 /// \details 2D arrays are used to represent parts of the device wiring data. In general, the 00122 /// nested arrays will not be identically sized, so we provide no deep constructor here. 00123 /// See Array for more details on the superclass. 00124 template <class T> class Array2D : public Array< Array<T> > { 00125 protected: 00126 // types 00127 /// \brief Typedef for the base class. 00128 typedef Array< Array<T> > super; 00129 public: 00130 // constructors 00131 /// \brief Null constructor. 00132 Array2D<T>(void) : super() {} 00133 /// \brief Public constructor. 00134 /// \param inSize The size of the outer array. The inner arrays will be constructed with 00135 /// their unsized default constructor. 00136 Array2D<T>(uint32_t inSize) : super(inSize) {} 00137 }; 00138 00139 } // namespace architecture 00140 } // namespace torc 00141 00142 #endif // TORC_ARCHITECTURE_ARRAY_HPP