diff options
Diffstat (limited to 'meowpp/self.h')
-rw-r--r-- | meowpp/self.h | 346 |
1 files changed, 0 insertions, 346 deletions
diff --git a/meowpp/self.h b/meowpp/self.h deleted file mode 100644 index f58ef35..0000000 --- a/meowpp/self.h +++ /dev/null @@ -1,346 +0,0 @@ -#ifndef MEOWPP_SELF_H_ -#define MEOWPP_SELF_H_ - -#include <cstdlib> -#include <algorithm> - -namespace meow { - -/*! - *@brief For developer to pack the attributes of a class. - * - * The idaa comes from python. - * Default C++'s reference machanism is very unflexible because a reference - * variable can only reference to an object without changing to other object. - * - * With this technique, it can achieve Copy-On-Write(COR) mechanism at - * background and have a reference mechanism which much more flexible - * then the one C++ has. - * - * Sample code: - *@code{.cpp} - * class A { - * private: - * struct Myself { - * int data; - * - * Myself() { // Necessary - * data = 0; - * } - * - * Myself(Myself const& b): data(b.data) { // Necessary, copy constructor - * } - * - * ~Myself() { - * } - * - * bool operator==(Myself const& b) const { // Optional (this method will - * // be called only if you use - * // Self::equal() method) - * return (data == b.data); - * } - * }; - * - * Self<Myself> const self; // Here we use 'constant' data type in - * // order to have a coutious coding style - * // and allow the COR mechanism to clone - * // data only when we really want to - * // modify them. - * public: - * A(): self() { } // Default constructor - * - * A(A const& a): self(a.self, COPY_FROM) { } // Copy constructor. You must - * // tell me which way of - * // duplicating should I use. - * // It strongly recommended you - * // use COYP_FROM for keeping the - * // C++'s original behavior. - * ~A() { } - * - * int getMemember(int wh) const { - * return self->data; // Use 'operator->()' to get the pointer of the data - * // The pointer is constant or not will depend on - * // whether the left side variable of '->' is - * // constant or not. - * // If we just want to read the data, use - * // 'self' instead of 'self()' - * } - * void setMemeber(int k) { - * self()->data = k; // As a result of 'self()' returning a non-constant - * // reference of itself, here we get the permission - * // for modiying data. - * // So now we can observe that if you type - * // 'Self<Myself> self' instead of the one above, - * // 'self' and 'self()' will become the same one and - * // both of them allow you using '->' for getting - * // writing permission. At the same time, the COR - * // machanism will become useless because everytime - * // you want to access the date, Self will copy the - * // data to prevent you to modify it no matter that - * // you might just want to read it. - * } - * - * A referenceFrom(A const& a) { - * self.referenceFrom(a.self); - * } - * - * A copyFrom(A const& a) { - * self.copyFrom(a.self); - * } - * - * A& operator=(A const& b) { // If you really like to use operator=, it - * // strongly recommended you use 'copyFrom()' for - * // keeping C++'s original behavior. - * copyFrom(b); - * } - * }; - *@endcode - * Note that 'referenceFrom()' will cause the two object become the same one, - * Which means that if you do something like '\c a.referenceFrom(b); - * \c a.copyFrom(c); ', the result is that the value of \c a,b,c will all the - * same one. - * - *@author cathook - * - *@warning This class disabled the method \c operator= and copy constructor - * in order to prevent unexplicit default behavior, so if you want - * to have one of them (or both), you must implement yourself - */ -template<class Data> -class Self { -public: - /*! - * @brief Kind of ways of duplicating - */ - enum DuplicateType { - COPY_FROM, //!< Normal copy operation - REFERENCE_FROM //!< By reference, much like pointer's copy operation - }; -private: - class Body { - private: - struct Kernel { - Data* data_; - size_t counter_; - Body const* master_; - - Kernel(Body const* master): - data_(new Data( )), counter_(1), master_(master) { - } - - Kernel(Body const* master, Data const& d): - data_(new Data(d)), counter_(1), master_(master) { - } - - ~Kernel() { - delete data_; - } - }; - - Kernel* pointer_; - size_t counter_; - - void clear() { - --(pointer_->counter_); - if (pointer_->counter_ <= 0) { - delete pointer_; - } - else if (pointer_->master_ == this) { - pointer_->master_ = NULL; - } - } - public: - Body( ): pointer_(new Kernel(this )), counter_(1) { } - Body(Data const& d): pointer_(new Kernel(this, d)), counter_(1) { } - Body(Body const& b): pointer_(b.pointer_ ), counter_(1) { - ++(pointer_->counter_); - } - - ~Body() { - clear(); - } - - Body& copyFrom(Body const& b) { - clear(); - pointer_ = b.pointer_; - ++(pointer_->counter_); - return *this; - } - - Data const* access() const { - return pointer_->data_; - } - - Data* modify() { - if (pointer_->counter_ > 1) { - --(pointer_->counter_); - Kernel* dupl = new Kernel(this, *pointer_->data_); - if (pointer_->master_ == this) { - std::swap(pointer_->data_, dupl->data_); - pointer_->master_ = NULL; - } - pointer_ = dupl; - } - else if (pointer_->master_ == NULL) { - pointer_->master_ = this; - } - return pointer_->data_; - } - - int attach() { - return ++counter_; - } - - int detach() { - return --counter_; - } - }; - - Body* body_; - - void clear() { - if (body_->detach() <= 0) { - delete body_; - } - } -public: - /*! - * @brief constructor with a real entity - */ - Self(): body_(new Body()) { - } - - /*! - * @brief connstructor with a real entity with it using its copy constructor - * - * @param [in] d Inital data - */ - Self(Data const& d): body_(new Body(d)) { - } - - /*! - * @brief constructor with given another Self - * - * @param [in] b Another Self object. - * @param [in] d To indicate type of way of duplicating - */ - Self(Self const& b, DuplicateType d) { - switch(d) { - case COPY_FROM: - body_ = new Body(*b.body_); - break; - case REFERENCE_FROM: - body_ = b.body_; - body_->attach(); - break; - } - } - - //! @brief Disallow copy constructor - Self(Self const& b); - - //! @brief destructor - ~Self() { - clear(); - } - - //! @brief Return the constant pointer to the data - Data const* operator->() const { - return body_->access(); - } - - /*! @brief Return the non-constant pointer to the data (COR's clone might - * occure here. - */ - Data* operator->() { - return body_->modify(); - } - - //! @brief Return the non-constant reference of \c *this - Self& operator()() const { - return *((Self*)this); - } - - /*! - * @brief Copy the gived \c Self to myself - * - * @param [in] s gived \c Self - * @return *this - */ - Self const& copyFrom(Self const& s) { - if (body_->access() != s.body_->access()) { - body_->copyFrom(*s.body_); - } - return *this; - } - - /*! - * @brief Reference myself from given \c Self object. - * - * @param [in] s given \c Self - * @return *this - */ - Self const& referenceFrom(Self const& s) { - if (body_ != s.body_) { - clear(); - body_ = s.body_; - body_->attach(); - } - return *this; - } - - /*! - * @brief call \c copyFrom() or \c referenceFrom() depend on your instruction - * - * @param [in] s gived \c Self object - * @param [in] t instruction - * @return *this - */ - Self const& duplicateFrom(Self const& s, DuplicateType t) { - switch(t) { - case COPY_FROM : return copyFrom(s); - case REFERENCE_FROM: return referenceFrom(s); - } - return *this; - } - - /*! - * @brief Compare tht if the gived \c Self object is reference from the same - * object of me - * - * @param [in] s gived \c Self object - * @return \c true if we are referenced to the same object. - */ - bool same(Self const& s) const { - return (body_ == s.body_); - } - - /*! - * @brief Compare that the data are the same. - * - * @param [in] s another \c Self object - * @return \c true if the data are same. - * - * @note This will need the method 'Data::equal()' - */ - bool equal(Self const& s) const { - if (same(s) || body_->access() == s.body_->access()) return true; - return (*body_->access() == *s.body_->access()); - } - - /*! - * @brief Order compare by reference pointer. - * - * @param [in] s another \c Self object - */ - bool referenceLess(Self const& s) const { - return (body_ < s.body_); - } - - //! @brief Disallow default \c 'operator=' - void operator=(Self const& a); -}; - -} // meow - -#endif // MEOWPP_SELF_H_ |