degate  0.1.2
DeepCopyable.h
Go to the documentation of this file.
00001 /* -*-c++-*-
00002 
00003  This file is part of the IC reverse engineering tool degate.
00004 
00005  Copyright 2012 Robert Nitsch
00006 
00007  Degate 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 3 of the License, or
00010  any later version.
00011 
00012  Degate 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 degate. If not, see <http://www.gnu.org/licenses/>.
00019 */
00020 
00021 #ifndef DEEPCOPYABLE_H
00022 #define DEEPCOPYABLE_H
00023 
00024 #include <map>
00025 #include <memory>
00026 
00027 namespace degate {
00028 
00029 class DeepCopyable;
00030 typedef std::shared_ptr<DeepCopyable> DeepCopyable_shptr;
00031 typedef std::shared_ptr<const DeepCopyable> c_DeepCopyable_shptr;
00032 
00033 class DeepCopyableBase {
00034 public:
00035   typedef std::map<c_DeepCopyable_shptr, DeepCopyable_shptr> oldnew_t;
00036 protected:
00037   /**
00038    * @brief Deep-copy all members to \a destination.
00039    * 
00040    * @todo Find out whether the default assignment operator can be used to simplify implementations of this method.
00041    */
00042   virtual void cloneDeepInto(DeepCopyable_shptr destination, oldnew_t *oldnew) const = 0;
00043 };
00044 
00045 /**
00046  * DeepCopyable is a type for cloneable objects (deep-copyable).
00047  *
00048  * You can think of an object hierarchy as a graph. To make a deep-copy possible,
00049  * all leafs of the graph must implement the DeepCopyable interface, and the inner nodes
00050  * must implement the DeepCopyableBase interface. Then, it is possible to recursively
00051  * visit all nodes in the graph by calling cloneDeep().
00052  *
00053  * The \a oldnew mapping is used to ensure that each object in the object hierarchy
00054  * is copied only once, even if there are multiple paths to the object in the
00055  * hierarchy. This is achieved by searching for an existing clone in the map
00056  * before cloning the respective object.
00057  */
00058 class DeepCopyable : public DeepCopyableBase, public std::enable_shared_from_this<DeepCopyable> {
00059 public:
00060   /**
00061    * @brief Return a copy of this object, but with all references to other DeepCopyables cleared (e.g. set to 0-pointer).
00062    */
00063   virtual DeepCopyable_shptr cloneShallow() const = 0;
00064   
00065   /**
00066    * @brief Return a deep-copy of this object, i.e. with all DeepCopyable members deep-copied themselves.
00067    * 
00068    * Use \a oldnew to avoid cloning objects multiple times.
00069    */
00070   virtual DeepCopyable_shptr cloneDeep(oldnew_t *oldnew) const;
00071 protected:
00072   /**
00073    * @brief Store o->cloneShallow() in oldnew[o], unless there already exists such a clone.
00074    * 
00075    * This should be used as convenience function in cloneDeep() implementations.
00076    */
00077   static bool cloneOnce(const c_DeepCopyable_shptr &o, oldnew_t *oldnew);
00078 };
00079 
00080 }
00081 
00082 #endif  /* DEEPCOPYABLE_H */