00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00046 #ifndef CONTROL_COMMAND_IMPL_CLONE_BUILDER_H
00047 #define CONTROL_COMMAND_IMPL_CLONE_BUILDER_H
00048
00049
00050
00051 #include "proc/control/command-mutation.hpp"
00052 #include "lib/typed-allocation-manager.hpp"
00053 #include "lib/opaque-holder.hpp"
00054
00055
00056 #include <boost/noncopyable.hpp>
00057
00058
00059
00060
00061
00062
00063 namespace control {
00064
00065 using lib::TypedAllocationManager;
00066
00067
00068 using lib::InPlaceBuffer;
00069
00070
00071 namespace impl {
00072
00073 struct CloneContext
00074 {
00075 virtual ~CloneContext() {}
00076
00077 virtual UndoMutation const& getUndoFunc() { NOTREACHED(); }
00078 virtual PClo const& getClosure() { NOTREACHED(); }
00079 virtual bool isValid() { return false; }
00080 };
00081
00082 class ClonedContext
00083 : public CloneContext
00084 {
00085 PClo newClosure_;
00086 UndoMutation newUndoFunctor_;
00087
00088 virtual UndoMutation const& getUndoFunc() { return newUndoFunctor_; }
00089 virtual PClo const& getClosure() { return newClosure_; }
00090 virtual bool isValid() { return true; }
00091
00092
00098 template<typename ARG>
00099 ARG&
00100 downcast()
00101 {
00102 REQUIRE (INSTANCEOF (ARG, newClosure_.get()));
00103
00104 return static_cast<ARG&> (*newClosure_);
00105 }
00106
00107
00108 public:
00109
00110 template<typename ARG>
00111 ClonedContext ( ARG const& origArgHolder
00112 , TypedAllocationManager& allocator
00113 )
00114 : newClosure_(allocator.create<ARG> (origArgHolder))
00115 , newUndoFunctor_(downcast<ARG>().getMementoWiring())
00116 { }
00117 };
00118
00119 }
00120
00121
00122
00123
00124
00132 class CommandImplCloneBuilder
00133 : public boost::noncopyable
00134 {
00135 typedef InPlaceBuffer<impl::CloneContext, sizeof(impl::ClonedContext)> ContextHolder;
00136
00137 TypedAllocationManager& allocator_;
00138 ContextHolder newContext_;
00139
00140 public:
00141 CommandImplCloneBuilder (TypedAllocationManager& allo)
00142 : allocator_(allo)
00143 { }
00144
00145
00155 template<typename ARG>
00156 void
00157 buildCloneContext (ARG const& origArgHolder)
00158 {
00159 REQUIRE (!newContext_->isValid(), "Lifecycle-Error");
00160
00161 newContext_.create<impl::ClonedContext> (origArgHolder, allocator_);
00162 }
00163
00164
00165
00167 UndoMutation const&
00168 clonedUndoMutation ()
00169 {
00170 REQUIRE (newContext_->isValid());
00171 return newContext_->getUndoFunc();
00172 }
00173
00174
00177 PClo const&
00178 clonedClosuere ()
00179 {
00180 REQUIRE (newContext_->isValid());
00181 return newContext_->getClosure();
00182 }
00183
00184 };
00185
00186
00187
00188
00189
00190 }
00191 #endif