aboutsummaryrefslogtreecommitdiffstats
path: root/meowpp/self.h
diff options
context:
space:
mode:
Diffstat (limited to 'meowpp/self.h')
-rw-r--r--meowpp/self.h346
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_