AbstractValue.h

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 2006-2007 by Peter Dimov.
00004 
00005 This file is part of Calitko (http://www.calitko.org).
00006 
00007 Calitko is free software; you can redistribute it and/or modify
00008 it under the terms of the GNU General Public License as published by
00009 the Free Software Foundation; either version 2 of the License, or
00010 (at your option) any later version.
00011 
00012 Calitko is distributed in the hope that it will be useful,
00013 but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Calitko; if not, write to the Free Software
00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020 
00021 */
00022 
00023 #ifndef UTILS__ABSTRACT_VALUE_H
00024 #define UTILS__ABSTRACT_VALUE_H
00025 
00026 #include "Imports.h"
00027 
00028 namespace Utils {
00029 
00031 
00123 template <typename AbstractType,
00124           typename NullObjectType,
00125           typename HierarchyRoot = AbstractType>
00126 class AbstractValue
00127 {
00128 public:
00130 
00133     AbstractValue()
00134     : object_ (new NullObjectType())
00135     {}
00136 
00138 
00142     AbstractValue (const AbstractType &object)
00143     : object_ (object.copy())
00144     {}
00145 
00147 
00151     AbstractValue (const AbstractValue &other)
00152     : object_ (other.object_->copy())
00153     {}
00154 
00156 
00163     AbstractValue & operator= (const AbstractValue &other)
00164     {
00165         object_ = other.object_->copy();
00166         return *this;
00167     }
00168 
00170 
00178     bool operator== (const AbstractValue &other) const
00179     {
00180         return typeid (*object_) == typeid (*other.object_)
00181                 && object_->isEqualTo (*other.object_);
00182     }
00183 
00185 
00193     bool operator!= (const AbstractValue &other) const
00194     {
00195         return !(*this == other);
00196     }
00197 
00199     AbstractType & operator*()
00200     {
00201         // We need the cast because we store an auto_ptr <HierarchyRoot>:
00202         return static_cast <AbstractType &> (*object_);
00203     }
00204 
00206     const AbstractType & operator*() const
00207     {
00208         // We need the cast because we store an auto_ptr <HierarchyRoot>:
00209         return static_cast <const AbstractType &> (*object_);
00210     }
00211 
00213     AbstractType * operator->()
00214     {
00215         // We need the cast because we store an auto_ptr <HierarchyRoot>:
00216         return static_cast <AbstractType *> (object_.get());
00217     }
00218 
00220     const AbstractType * operator->() const
00221     {
00222         // We need the cast because we store an auto_ptr <HierarchyRoot>:
00223         return static_cast <const AbstractType *> (object_.get());
00224     }
00225 
00227 
00242     template <typename RelatedAbstractType, typename RelatedNullType>
00243     operator AbstractValue <RelatedAbstractType,
00244                             RelatedNullType,
00245                             HierarchyRoot>() const
00246     {
00247         // The dynamic_cast would allow us to always perform a safe "up-cast" or
00248         // "down-cast" to AbstractValue instantiation for a related type.
00249         return AbstractValue <RelatedAbstractType,
00250                               RelatedNullType,
00251                               HierarchyRoot>
00252             (dynamic_cast <const RelatedAbstractType &> (*object_.get()));
00253     }
00254 
00255 private:
00257     auto_ptr <HierarchyRoot>        object_;
00258 };
00259 
00260 } // namespace Utils
00261 
00262 #endif // UTILS__ABSTRACT_VALUE_H