NeuralSimUtils.H

Go to the documentation of this file.
00001 /*!@file ModelNeuron/NeuralSimUtils.H A bunch of utility classes,
00002    mostly some template idioms inspired from Alexandrescu, 2001*/
00003 
00004 // //////////////////////////////////////////////////////////////////// //
00005 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the //
00006 // University of Southern California (USC) and the iLab at USC.         //
00007 // See http://iLab.usc.edu for information about this project.          //
00008 // //////////////////////////////////////////////////////////////////// //
00009 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00010 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00011 // in Visual Environments, and Applications'' by Christof Koch and      //
00012 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00013 // pending; application number 09/912,225 filed July 23, 2001; see      //
00014 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00015 // //////////////////////////////////////////////////////////////////// //
00016 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00017 //                                                                      //
00018 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00019 // redistribute it and/or modify it under the terms of the GNU General  //
00020 // Public License as published by the Free Software Foundation; either  //
00021 // version 2 of the License, or (at your option) any later version.     //
00022 //                                                                      //
00023 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00024 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00025 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00026 // PURPOSE.  See the GNU General Public License for more details.       //
00027 //                                                                      //
00028 // You should have received a copy of the GNU General Public License    //
00029 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00030 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00031 // Boston, MA 02111-1307 USA.                                           //
00032 // //////////////////////////////////////////////////////////////////// //
00033 //
00034 // Primary maintainer for this file: David J. Berg <dberg@usc.edu>
00035 // $HeadURL:svn://ilab.usc.edu/trunk/saliency/src/ModelNeuron/NeuralSimUtils.H$
00036 
00037 #ifndef MODELNEURON_NEURALSIMUTILS_H_DEFINED
00038 #define MODELNEURON_NEURALSIMUTILS_H_DEFINED
00039 
00040 #ifdef INVT_USE_CPPOX//we need c++ 0X features for this to work
00041 
00042 #include "Image/Image.H"
00043 #include "GenericUtils/GenericFactory.H"
00044 #include "GenericUtils/CreateFunctor.H"
00045 
00046 #include <iterator>
00047 #include <vector>
00048 
00049 namespace nsu
00050 {
00051 // ######################################################################
00052 // Used to represent null and empty types 
00053 // ######################################################################
00054   class NullType { };
00055   class EmptyType { };
00056 
00057 // ######################################################################
00058 // A simple class to 'typeify' an integral constant, useful for making
00059 // decisions about possible control paths at compile time. From
00060 // Alexandrescu, 2001
00061 // ######################################################################
00062   template <int type>
00063   struct Int2Type
00064   {
00065     enum { value = type };
00066   };
00067   
00068 // ######################################################################
00069 // A simple class to hold type information. This is useful as a light
00070 // weight way of choosing overloaded functions from types. From
00071 // Alexandrescu, 2001
00072 // ######################################################################
00073   template <class Type>
00074   struct Type2Type 
00075   {
00076     typedef Type type;
00077   };
00078 
00079   // ######################################################################
00080   // A simple class to choose one of two different types, from a compile
00081   // time decision. The type an be retrieved by: 
00082   //
00083   // Select<boolean expression, Class1, class2>::Result 
00084   //
00085   // Where if expression is true, ::Result will be of type Class1, else ::Result
00086   // will be of type Class2
00087   // From Alexandrescu, 2001
00088   // ######################################################################   
00089   template <bool expression, class C_true, class C_false>
00090   struct SelectType //if expression is true, Type will be of C_true type.
00091   {
00092     typedef C_true Type;
00093   };
00094   
00095   template <class C_true, class C_false>
00096   struct SelectType<false, C_true, C_false> //if false, call this specialization
00097   {
00098     typedef C_false Type;
00099   };
00100   
00101   // ###################################################################### 
00102   // A type traits class to deterimine properties of a template type
00103   // ######################################################################   
00104   template <typename T>
00105   class TypeTraits 
00106   {
00107   private:
00108     template <class U> struct PointerTraits 
00109     {
00110       enum { result = false };
00111       typedef U PointeeType;
00112     };
00113 
00114     template <class U> struct PointerTraits <U*>
00115     {
00116       enum { result = true };
00117       typedef U PointeeType;
00118     };
00119 
00120   public:
00121     enum { isPointer = PointerTraits<T>::result };
00122     typedef typename PointerTraits<T>::PointeeType PointeeType;
00123   };
00124 
00125   // ###################################################################### 
00126   //An extension to std::vector that handles polymorphic types. Put in a pointer to a virtual base class, but use the
00127   //access operators and iterators as if you had a non-pointer type. The virtual base must supply a clone() method which
00128   //makes a polymorphic deep copy. Derived classes must override clone() to create the correct object, and then return a
00129   //pointer to the base class. The vector will call delete on its members when they need to be destroyed. For safety,
00130   //the virtual pas should make its copy constructor and assignment operator protected or private.
00131 
00132   //A non-pointer object can be supplied and the vector works like a std::vector. The template specialization mechanism
00133   //chooses the classes and functions at compile time and on modern compilers this wrapper class should incure little or
00134   //no overhead.
00135 
00136   //The const/non-const iterators work just like std::vector iterators when the object is no polyphomic. When the vector
00137   //contains a polymorphic type, the iterators provided have an additional pointer() function, which returns a reference
00138   //to the underlying pointer at the iterators position in the array. Using this function could be very dangerous if you
00139   //don't know what your doing and is not reccommended, put provided for advanced uses. For polymophic classes non-const
00140   //iterators allow manipulation of the object or its pointer through pointer(). const iterators will forbid
00141   //modification of the object or its pointer through pointer(), but delete could still be called on it, so be carefull.
00142   //######################################################################
00143   template<class T>
00144   class vector
00145   {
00146     std::vector<T> itsV;
00147     
00148   public:
00149     typedef typename std::vector<T>::iterator iterator;
00150     typedef typename std::vector<T>::const_iterator const_iterator;
00151     typedef T Type;
00152     typedef EmptyType PointerType;
00153     enum {isPointer = 0 };
00154     
00155     // constructor
00156     vector() : itsV() { };
00157 
00158     // constructor
00159     vector(size_t size, const T& value) : itsV(size, value) { };
00160     
00161     //destructor
00162     ~vector() { };
00163     
00164     // return a reference
00165     T& operator[](const int pos) { return itsV[pos]; };//not save for assignment, use set_at
00166     const T& operator[](const int pos) const { return itsV[pos]; };
00167     
00168     // set an element at the specified position
00169     void set_at(const uint pos, const T& element) { itsV[pos] = element; };
00170 
00171     // push an element on
00172     void push_back(const T& element) { itsV.push_back(element); };
00173     
00174     // pop an element
00175     void pop_back() { itsV.pop_back(); };
00176     
00177     // reference to element at back
00178     T& back() { itsV.back(); };
00179     const T& back() const  { itsV.back(); };
00180     
00181     // reference to element at front
00182     T& front() { itsV.front(); };
00183     const T& front() const { itsV.front(); };
00184     
00185     // get the size
00186     const size_t size() const {return itsV.size(); };
00187 
00188     // clear contents
00189     void clear() { itsV.clear(); };
00190     
00191     // get iterator to element at front
00192     iterator begin() { return itsV.begin(); };
00193     const_iterator begin() const { return itsV.begin(); };
00194     
00195     //get iterator to element at back
00196     iterator end() { return itsV.end(); };
00197     const_iterator end() const { return itsV.end(); };
00198 
00199     //return true if the element as pos is null
00200     const bool isNull(const uint pos) const {return false; };
00201   };
00202 
00203   // ######################################################################
00204   // specialization for pointer type
00205   // ######################################################################
00206   template<class T>
00207   class vector<T*> //in this case, T will be the pointee type
00208   {
00209     template<class U> class cp_iterator; //forward declaration
00210     
00211     //define iterator
00212     template <class U> //U will be the pointee type
00213     class p_iterator : public std::iterator<std::random_access_iterator_tag, U>
00214     {
00215       friend class cp_iterator<U>;
00216       typedef unsigned long diff_t;   
00217       typedef typename std::vector<U*>::iterator v_iterator;
00218       v_iterator iter;
00219       
00220     public:
00221       //constructors 
00222       p_iterator() : iter() { };
00223       p_iterator(const p_iterator& rhs) : iter(rhs.iter) { };
00224       p_iterator(const v_iterator& rhs) : iter(rhs) { };
00225 
00226       //default assignment OK
00227       
00228       //logical
00229       bool operator==(const p_iterator& rhs) const { return iter == rhs.iter; };
00230       bool operator!=(const p_iterator& rhs) const { return iter != rhs.iter; };
00231       bool operator<(const p_iterator& rhs) const { return iter < rhs.iter; };
00232       bool operator<=(const p_iterator& rhs) const { return iter <= rhs.iter; };
00233       bool operator>(const p_iterator& rhs) const { return iter > rhs.iter; };
00234       bool operator>=(const p_iterator& rhs) const { return iter >= rhs.iter; };
00235       
00236       //increment and decrement
00237       p_iterator& operator++() {
00238         ++iter;
00239         return *this;
00240       };
00241       p_iterator operator++(int) {
00242         p_iterator tmp = *this;
00243         ++iter;
00244         return tmp;
00245       };
00246       void operator+=(diff_t d) { 
00247         iter += d; };
00248       p_iterator& operator--() {
00249         --iter;
00250         return *this;
00251       };
00252       p_iterator operator--(int) {
00253         p_iterator tmp = *this;
00254         --iter; 
00255         return tmp;
00256       };
00257       void operator-=(diff_t d) { 
00258         iter -= d; };
00259       
00260       //access
00261       U& operator*() { return **iter; };
00262       U*& pointer() { return *iter; };
00263       U* operator->() { return *iter; }; //evaluated as *( *iter ).
00264     };
00265 
00266     //define const iterator
00267     template <class U> //U will be the pointee type
00268     class cp_iterator : public std::iterator<std::random_access_iterator_tag, U>
00269     {
00270       typedef unsigned long diff_t;   
00271       typedef typename std::vector<U*>::const_iterator v_iterator;
00272       v_iterator iter;
00273       
00274     public:
00275       //constructors 
00276       cp_iterator() : iter() { };
00277       cp_iterator(const cp_iterator& rhs) : iter(rhs.iter) { };
00278       cp_iterator(const p_iterator<U>& rhs) : iter(rhs.iter) { };
00279       cp_iterator(const v_iterator& rhs) : iter(rhs) { };
00280 
00281       //default assignment OK
00282       
00283       //logical
00284       bool operator==(const cp_iterator& rhs) const {return iter == rhs.iter; };
00285       bool operator!=(const cp_iterator& rhs) const {return iter != rhs.iter; };
00286       bool operator<(const cp_iterator& rhs) const {return iter < rhs.iter; };
00287       bool operator<=(const cp_iterator& rhs) const {return iter <= rhs.iter; };
00288       bool operator>(const cp_iterator& rhs) const {return iter > rhs.iter; };
00289       bool operator>=(const cp_iterator& rhs) const {return iter >= rhs.iter; };
00290       
00291       //increment and decrement
00292       cp_iterator& operator++() {
00293         ++iter;
00294         return *this;
00295       };
00296       cp_iterator operator++(int) {
00297         cp_iterator tmp = *this;
00298         ++iter;
00299         return tmp;
00300       };
00301       void operator+=(diff_t d) { 
00302         iter += d; };
00303       cp_iterator& operator--() {
00304         --iter;
00305         return *this;
00306       };
00307       cp_iterator operator--(int) {
00308         cp_iterator tmp = *this;
00309         --iter; 
00310         return tmp;
00311       };
00312       void operator-=(diff_t d) { 
00313         iter -= d; };
00314       
00315       //access
00316       const U& operator*() const { return **iter; };
00317       const U* const pointer() const { return *iter; };
00318       const U* operator->() const { return *iter; }; //evaluated as *( *iter ).
00319     };
00320 
00321     //private members of vector<T*>
00322     //our storage container
00323     std::vector<T*> itsV;
00324     
00325     //for our storage container iterator
00326     typedef typename std::vector<T*>::const_iterator v_iterator;
00327     
00328   public:
00329     typedef p_iterator<T> iterator;
00330     typedef cp_iterator<T> const_iterator;
00331     typedef T Type;
00332     typedef T* PointerType;
00333     enum {isPointer = 1 };
00334     
00335     // constructor
00336     vector() : itsV() { };
00337 
00338     // constructor
00339     vector(size_t size, const T& value) : itsV()
00340     { 
00341       for (uint ii = 0; ii < (uint)size; ++ii)
00342         itsV.push_back(value.clone());
00343     };
00344 
00345     //copy constructor 
00346     vector(const vector& rhs) 
00347     { 
00348       clear();
00349       v_iterator i(rhs.itsV.begin()), end(rhs.itsV.end());
00350       while (i != end)
00351         itsV.push_back( (*i++)->clone() );
00352     };
00353 
00354     //assignment operator
00355     vector& operator=(const vector& rhs)
00356     {
00357       if (this != &rhs)
00358         {
00359           clear();
00360           v_iterator i(rhs.itsV.begin()), end(rhs.itsV.end());
00361           while (i != end)
00362             itsV.push_back( (*i++)->clone() );
00363         }
00364       return *this;
00365     };
00366     
00367     //destructor
00368     ~vector()   
00369     {     
00370       clear();
00371     };
00372     
00373     // return a reference
00374     T& operator[](const int pos) { return *itsV[pos]; };//not safe for assignment, use set_at
00375     const T& operator[](const int pos) const { return *itsV[pos]; };
00376 
00377     // set an element at the specified position
00378     void set_at(const uint pos, const T& element) { delete itsV[pos]; itsV[pos] = element.clone(); };
00379        
00380     // push an element on, when the element is a reference
00381     void push_back(const T& element) { itsV.push_back(element.clone()); };
00382 
00383     // pop an element
00384     void pop_back() { delete itsV.back(); itsV.pop_back(); };
00385     
00386     // reference to element at back
00387     T& back() { *itsV.back(); };
00388     const T& back() const  { *itsV.back(); };
00389     
00390     // reference to element at front
00391     T& front() { *itsV.front(); };
00392     const T& front() const { *itsV.front(); };
00393     
00394     // get the size
00395     const size_t size() const {return itsV.size(); };
00396 
00397     // clear contents
00398     void clear() 
00399     {     
00400       v_iterator begin(itsV.begin()), end(itsV.end());
00401       while (begin != end)
00402         delete *begin++; 
00403       itsV.clear();
00404     };
00405     
00406     // get iterator to element at front
00407     iterator begin() { return iterator(itsV.begin()); };
00408     const_iterator begin() const { return const_iterator(itsV.begin()); };
00409     
00410     //get iterator to element at back
00411     iterator end() { return iterator(itsV.end()); };
00412     const_iterator end() const { return const_iterator(itsV.end()); };
00413 
00414     //check if the element at pos is null
00415     const bool isNull(const uint pos) const { return (itsV[pos] == NULL) ? true : false; };
00416   };
00417 
00418 // ######################################################################
00419 // A wrapper for an iterator, that is an iterator itself. If the
00420 // iterator's ::value_type is a pointer than dereferencing this
00421 // iterator will return a reference by dereferning the pointer that
00422 // the iterator points to. If the ::value_type is not a pointer, the
00423 // iterator behaves like a normal iterator.
00424 // ######################################################################
00425 
00426 /*  template <class Itr> //Itr will be an iterator
00427   class p_iterator
00428   { 
00429   private:
00430     Itr iter; //the underylying iterator
00431     typedef unsigned long diff_t;   
00432     
00433   public:
00434     typedef typename Itr::value_type value_type;
00435     typedef typename Itr::pointer pointer;
00436     typedef typename Itr::reference reference;
00437     typedef ptrdiff_t difference_type;
00438     typedef std::random_access_iterator_tag iterator_category;
00439     
00440     //constructors 
00441     p_iterator(const Itr& rhs) : iter(rhs) { };
00442     
00443     //logical
00444     bool operator==(const p_iterator& rhs) const { return iter == rhs.iter; };
00445     bool operator!=(const p_iterator& rhs) const { return iter != rhs.iter; };
00446     bool operator<(const p_iterator& rhs) const { return iter < rhs.iter; };
00447     bool operator<=(const p_iterator& rhs) const { return iter <= rhs.iter; };
00448     bool operator>(const p_iterator& rhs) const { return iter > rhs.iter; };
00449     bool operator>=(const p_iterator& rhs) const { return iter >= rhs.iter; };
00450     
00451     //increase, decrease iterator location
00452     p_iterator& operator++() {
00453       ++iter;
00454       return *this;
00455     };
00456     p_iterator operator++(int) {
00457       p_iterator tmp = *this;
00458       ++iter;
00459       return tmp;
00460     };
00461     void operator+=(diff_t d)
00462     { iter += d; };
00463     p_iterator& operator--() {
00464       --iter;
00465       return *this;
00466     };
00467     p_iterator operator--(int) {
00468       p_iterator tmp = *this;
00469       --iter; 
00470       return tmp;
00471     };
00472     void operator-=(diff_t d)
00473     { iter += d; }
00474 
00475     //access correct deref and arrow function based on whether the value_type is
00476     //a pointer or not.
00477     reference operator*() 
00478     { return deref( Int2Type<TypeTraits<value_type>::isPointer >() ); };
00479     
00480     pointer operator->() 
00481     { return arrow( Int2Type<TypeTraits<value_type>::isPointer >() ); };
00482 
00483     //where the true or false refers to whether or not the data is polymorphic
00484     reference deref(Int2Type<false>) 
00485     { return *iter; };
00486     
00487     reference deref(Int2Type<true>) 
00488     { return **iter; };
00489     
00490     pointer arrow(Int2Type<false>) 
00491     { return iter; };
00492     
00493     pointer arrow(Int2Type<true>) 
00494     { return  *iter; };
00495   };
00496 */
00497 
00498 /*  
00499 // ######################################################################
00500 // A simple iterator that takes a raw pointer and automatically double
00501 // dereferences pointer to pointers.
00502 // ######################################################################
00503   template <class T> class raw_iterator
00504   {
00505   private:
00506     //declare, but do not implement default p2p_traits. This way the
00507     //whole things will bail if a non-specialization is called
00508     template <class U> struct p2p_traits;
00509 
00510     //specializiation for when we are a pointer
00511     template <class U> struct p2p_traits<U*> 
00512     { 
00513       enum { result = false };
00514       typedef U value_type;
00515       typedef U* pointer;
00516       typedef U& reference;
00517     };
00518 
00519     //specializiation for when we are a pointer to a pointer
00520     template <class U> struct p2p_traits<U**> 
00521     { 
00522       enum { result = true } ;
00523       typedef U* value_type;
00524       typedef U* pointer;
00525       typedef U& reference;
00526     };
00527     
00528     //specialization when we are a pointer to a const pointer to a U
00529     template <class U> struct p2p_traits<U* const*>    
00530     {
00531       enum { result = true } ;
00532       typedef U* value_type;
00533       typedef U* pointer;
00534       typedef U& reference;
00535     };
00536 
00537     //a type for adding constants to iterators
00538     typedef unsigned long diff_t;       
00539 
00540     T iter;//our raw pointer
00541 
00542   public:
00543     typedef typename p2p_traits<T>::value_type value_type;
00544     typedef typename p2p_traits<T>::pointer pointer;
00545     typedef typename p2p_traits<T>::reference reference;
00546     typedef typename p2p_traits<T>::value_type& mutate_type;
00547 
00548     //constructors 
00549     raw_iterator(const T rhs) : iter(rhs) { };
00550     
00551     //logical
00552     bool operator==(const raw_iterator& rhs) const { return iter == rhs.iter; };
00553     bool operator!=(const raw_iterator& rhs) const { return iter != rhs.iter; };
00554     bool operator<(const raw_iterator& rhs) const { return iter < rhs.iter; };
00555     bool operator<=(const raw_iterator& rhs) const { return iter <= rhs.iter; };
00556     bool operator>(const raw_iterator& rhs) const { return iter > rhs.iter; };
00557     bool operator>=(const raw_iterator& rhs) const { return iter >= rhs.iter; };
00558     
00559     //increase, decrease iterator location
00560     raw_iterator& operator++() {
00561       ++iter;
00562       return *this;
00563     };
00564     raw_iterator operator++(int) {
00565       raw_iterator tmp = *this;
00566       ++iter;
00567       return tmp;
00568     };
00569     void operator+=(diff_t d)
00570     { iter += d; };
00571     raw_iterator& operator--() {
00572       --iter;
00573       return *this;
00574     };
00575     raw_iterator operator--(int) {
00576       raw_iterator tmp = *this;
00577       --iter; 
00578       return tmp;
00579     };
00580     void operator-=(diff_t d)
00581     { iter += d; };
00582     
00583     //access correct deref and arrow function based on whether the value_type is
00584     //a pointer or not.
00585     reference operator*() 
00586     { return deref( Int2Type<p2p_traits<T>::result >() ); };
00587     
00588     pointer operator->() 
00589     { return arrow( Int2Type<p2p_traits<T>::result >() ); };
00590 
00591     pointer topointer()
00592     { return arrow( Int2Type<TypeTraits<value_type>::isPointer >() ); };
00593 
00594     mutate_type mutate()
00595     { return *iter; };
00596 
00597     //where the true or false refers to whether or not the data is polymorphic
00598     reference deref(Int2Type<false>) 
00599     { return *iter; };
00600     
00601     reference deref(Int2Type<true>) 
00602     { return **iter; };
00603     
00604     pointer arrow(Int2Type<false>) 
00605     { return iter; };
00606     
00607     pointer arrow(Int2Type<true>) 
00608     { return *iter; };
00609   };
00610 */
00611 
00612   // ######################################################################
00613   //This function is used when the TypeCreator template argument of a 
00614   //ReusableFactory is a CreateFunctor, and one wants to set a parameter 
00615   //for all CreateFunctors in the the factory by the paramters type.  
00616   //######################################################################
00617   template <typename Factory, typename... Params>
00618   void setParameter(Factory& factory, const Params&... params)
00619   {
00620     typename Factory::iterator iter = factory.begin();
00621     while (iter != factory.end())
00622       {
00623         iter->second.updateParams(params...);
00624         ++iter;
00625       }
00626   }
00627 }//end namespace
00628 #endif
00629 #endif
00630 // ######################################################################
00631 /* So things look consistent in everyone's emacs... */
00632 /* Local Variables: */
00633 /* indent-tabs-mode: nil */
00634 /* End: */
Generated on Sun May 8 08:05:21 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3