Vaucanson 1.4
element.hxx
00001 // element.hxx: this file is part of the Vaucanson project.
00002 //
00003 // Vaucanson, a generic library for finite state machines.
00004 //
00005 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2011 The Vaucanson Group.
00006 //
00007 // This program is free software; you can redistribute it and/or
00008 // modify it under the terms of the GNU General Public License
00009 // as published by the Free Software Foundation; either version 2
00010 // of the License, or (at your option) any later version.
00011 //
00012 // The complete GNU General Public Licence Notice can be found as the
00013 // `COPYING' file in the root directory.
00014 //
00015 // The Vaucanson Group consists of people listed in the `AUTHORS' file.
00016 //
00017 #ifndef VCSN_DESIGN_PATTERN_ELEMENT_HXX
00018 # define VCSN_DESIGN_PATTERN_ELEMENT_HXX
00019 
00020 # include <vaucanson/misc/contract.hh>
00021 # include <vaucanson/design_pattern/element.hh>
00022 
00023 namespace vcsn {
00024 
00025   /*-------------.
00026   | Constructors |
00027   `-------------*/
00028 
00029   template <class S, class T>
00030   Element<S,T>::Element() :
00031     MetaElement<S, T>(),
00032     SetSlot<S>(),
00033     value_(op_default(SELECT(S), SELECT(T)))
00034   {
00035     static_assertion_(not dynamic_traits<S>::ret,
00036                       need_dynamic_structural_element);
00037   }
00038 
00039   /*--------------------------.
00040   | Constructors from Element |
00041   `--------------------------*/
00042 
00043   template <class S, class T>
00044   Element<S,T>::Element(const Element& other) :
00045     MetaElement<S, T>(other),
00046     SetSlot<S>(other),
00047     value_(other.value_)
00048   {}
00049 
00050   template <class S, class T>
00051   template<typename U>
00052   Element<S,T>::Element(const Element<S, U>& other) :
00053     SetSlot<S>(other.structure()),
00054     value_(op_convert(other.structure(), SELECT(T), other.value()))
00055   {}
00056 
00057   template <class S, class T>
00058   template<typename OtherS, typename U>
00059   Element<S,T>::Element(const Element<OtherS, U>& other)
00060     : SetSlot<S>(op_convert(SELECT(S), other.structure())),
00061       value_ (op_convert(this->_structure_get(), value_,
00062                          other.structure(), other.value()))
00063   {
00064   }
00065 
00066   /*-------------------------.
00067   | Constructors from values |
00068   `-------------------------*/
00069 
00070   template <class S, class T>
00071   Element<S,T>::Element(const T& other)
00072     : SetSlot<S> (),
00073       value_(op_convert(SELECT(S), SELECT(T), other))
00074   {
00075     static_assertion_(not dynamic_traits<S>::ret,
00076                       need_dynamic_structural_element);
00077   }
00078 
00079   template <class S, class T>
00080   template<typename U>
00081   Element<S,T>::Element(const U& other)
00082     : SetSlot<S> (),
00083       value_(op_convert(SELECT(S), SELECT(T), other))
00084   {
00085     static_assertion_(not dynamic_traits<S>::ret,
00086                       need_dynamic_structural_element);
00087   }
00088 
00089   /*--------------------------------------.
00090   | Constructors from structural elements |
00091   `--------------------------------------*/
00092 
00093   template <class S, class T>
00094   Element<S,T>::Element(const S& structure)
00095     : SetSlot<S>(structure),
00096       value_(op_default(this->_structure_get(), SELECT(T)))
00097   {}
00098 
00099   template <class S, class T>
00100   Element<S,T>::Element(const S& structure, const T& other)
00101     : SetSlot<S>(structure),
00102       value_(op_convert(this->_structure_get(), SELECT(T), other))
00103   {}
00104   template <class S, class T>
00105   template<typename U>
00106   Element<S,T>::Element(const S& structure, const U& other)
00107     : SetSlot<S>(structure),
00108       value_(op_convert(this->_structure_get(), SELECT(T), other))
00109   {}
00110 
00111   template <class S, class T>
00112   template<typename OtherS, typename U>
00113   Element<S,T>::Element(const S& structure, const Element<OtherS, U>& other)
00114     : SetSlot<S> (structure),
00115       value_(op_convert(this->_structure_get(), SELECT(T),
00116                         other.structure(), other.value()))
00117   {}
00118 
00119   /*-----------.
00120   | Assignment |
00121   `-----------*/
00122 
00123   template <class S, class T>
00124   Element<S,T>&
00125   Element<S,T>::operator = (const Element& other)
00126   {
00127     this->_structure_assign(other.structure());
00128     op_assign(structure(), other.structure(), value_, other.value());
00129     return *this;
00130   }
00131 
00132   template <class S, class T>
00133   template<typename U>
00134   Element<S,T>&
00135   Element<S,T>::operator = (const Element<S, U>& other)
00136   {
00137     this->_structure_assign(other.structure());
00138     op_assign(structure(), other.structure(), value_, other.value());
00139     return *this;
00140   }
00141 
00142   template <class S, class T>
00143   template<typename OtherS, typename U>
00144   Element<S,T>& Element<S,T>::operator = (const Element<OtherS, U>& other)
00145   {
00146     this->_structure_assign(op_convert(SELECT(S), other.structure()));
00147     op_assign(structure(), other.structure(), value_, other.value());
00148     return *this;
00149   }
00150 
00151   template <class S, class T>
00152   template<typename U>
00153   Element<S,T>& Element<S,T>::operator = (const U& other)
00154   {
00155     op_assign(structure(), value(), other);
00156     return *this;
00157   }
00158 
00159   /*------.
00160   | Sugar |
00161   `------*/
00162 
00163   template <class S, class T>
00164   void
00165   Element<S,T>::attach(const S& structure)
00166   {
00167     this->_structure_attach(structure);
00168   }
00169 
00170   template <class S, class T>
00171   const S&
00172   Element<S,T>::structure() const
00173   {
00174     return this->_structure_get();
00175   }
00176 
00177   template <class S, class T>
00178   T&    Element<S,T>::value()
00179   {
00180     return value_;
00181   }
00182 
00183   template <class S, class T>
00184   const T&      Element<S,T>::value() const
00185   {
00186     return value_;
00187   }
00188 
00189 } // vcsn
00190 
00191 
00192 #endif // ! VCSN_DESIGN_PATTERN_ELEMENT_HXX