File ImageVariable.patch of Package hugin
--- hugin-2018.0.0/src/hugin_base/panodata/ImageVariable.h 2015-07-22 20:56:43.000000000 +0200
+++ hugin-2018.0.0/src/hugin_base/panodata/ImageVariable.h 2018-06-21 16:38:59.784250653 +0200
@@ -23,6 +23,7 @@
#ifndef _PANODATA_IMAGEVARIABLE_H
#define _PANODATA_IMAGEVARIABLE_H
+#include <memory>
namespace HuginBase
@@ -149,71 +150,7 @@
bool isLinkedWith(const ImageVariable<Type> * otherVariable) const;
protected:
- /** @note
- * To keep the set of images linked, we store two pointers to other items
- * in the set, like a doubly linked list.
- * When copying variable values, we send it down the list in either
- * direction from the variable where setData(data) was called.
- *
- * @par
- * When unlinking, we point the items linked to to each other, replacing
- * their links to us.
- *
- * @par
- * When creating links, we need to check for circular lists. We check for
- * the presence of the item we are linking to in either direction before
- * linking to it. Since we are merging two sets that are either disjoint or
- * identical, this is enough.
- * The actual linking is done by linking the end of our list with the
- * beginning of the one containg the one we were passed in linkWith
- *
- * @par
- * To find the links, we search in both directions.
- *
- * @par
- * We search the previous links first, then the proceeding ones.
- */
-
- /** Find if we are linked to another ImageVariable earlier in the list.
- *
- * @param otherVariable the variable to look for
- * @return true if the variable is linked earilier in the list.
- */
- bool searchBackwards(const ImageVariable<Type> * otherVariable) const;
-
- /** Find if we are linked to another ImageVariable later in the list.
- *
- * @param otherVariable the variable to look for
- * @return true if the variable is linked later in the list.
- */
- bool searchForwards(const ImageVariable<Type> * otherVariable) const;
-
- /** Find the first item in the list of links with this ImageVariable.
- */
- ImageVariable<Type> * findStart();
-
- /** Find the last item in the list of links with this ImageVariable.
- */
- ImageVariable<Type> * findEnd();
-
- /** Set all linked variables earlier in the list to some given data.
- */
- void setBackwards(const Type data);
-
- /** Set all linked variables later in the list to some given data.
- */
- void setForwards(const Type data);
-
- ///////////////////
- // Member variables
-
- /// the data that will be returned when getData() is called.
- Type m_data;
-
- /// The item preceding us in the list of links
- ImageVariable<Type> * m_linkPrevious;
- /// The item following us in the list of links
- ImageVariable<Type> * m_linkNext;
+ std::shared_ptr<Type> m_ptr;
}; // ImageVariable class
/////////////////////////////
@@ -223,40 +160,23 @@
// Constructors
template <class Type>
-ImageVariable<Type>::ImageVariable()
+ImageVariable<Type>::ImageVariable() : m_ptr(new Type())
{
- // Start not linked to anything, so the variable is independant.
- m_linkPrevious = 0;
- m_linkNext = 0;
}
template <class Type>
-ImageVariable<Type>::ImageVariable(Type data)
+ImageVariable<Type>::ImageVariable(Type data) : m_ptr(new Type(data))
{
- // Use the data given
- m_data = data;
- // ...and start not linked to anything.
- m_linkPrevious = 0;
- m_linkNext = 0;
}
template <class Type>
-ImageVariable<Type>::ImageVariable(ImageVariable<Type> * link)
+ImageVariable<Type>::ImageVariable(ImageVariable<Type> * link) : m_ptr(link->m_ptr)
{
- // So we don't break linkWith:
- m_linkPrevious = 0;
- m_linkNext = 0;
- // make the link. Note this sets our data from linked variables.
- linkWith(link);
}
template <class Type>
-ImageVariable<Type>::ImageVariable(const ImageVariable<Type> & source)
+ImageVariable<Type>::ImageVariable(const ImageVariable<Type> & source) : m_ptr(new Type(*source.m_ptr))
{
- // When creating a copy, make independant.
- m_data = source.m_data;
- m_linkNext = 0;
- m_linkPrevious = 0;
}
// Destructor
@@ -264,9 +185,6 @@
template <class Type>
ImageVariable<Type>::~ImageVariable()
{
- // We will need to remove the links to this variable to keep the list sane.
- removeLinks();
- // it is safe to delete this object now.
}
// Other public member functions
@@ -274,138 +192,50 @@
template <class Type>
Type ImageVariable<Type>::getData() const
{
- return m_data;
+ return *m_ptr;
}
template <class Type>
void ImageVariable<Type>::setData(const Type data)
{
- /* We keep multiple copies of the data.
- * Hopefully the data isn't too large, and setData is called far less often
- * then getData, so it should be fast enough this way.
- */
- // set all the linked variables.
- // these both set this variables data.
- setBackwards(data);
- setForwards(data);
+ *m_ptr = data;
}
template <class Type>
void ImageVariable<Type>::linkWith(ImageVariable<Type> * link)
{
// We need to first check that we aren't linked already.
- if (searchBackwards(link) || searchForwards(link))
+ if (m_ptr == link->m_ptr)
{
DEBUG_INFO("Attempt to link already linked variables");
return;
}
else
{
- // not linked, it is safe to merge them.
- /* we need to merge the two sets together. We link the end of the list
- * with this object in it to the beginning of the list passed to us.
- */
- ImageVariable<Type> *end = findEnd();
- ImageVariable<Type> *beginning = link->findStart();
- end->m_linkNext = beginning;
- beginning->m_linkPrevious = end;
- // now we must set the data from what we were linked to.
- /* the link target has the same data, but the stuff previously linked
- * with us might have something different.
- */
- setBackwards(link->m_data);
+ if (m_ptr.use_count() > 1) {
+ DEBUG_INFO("linked");
+ }
+ m_ptr = link->m_ptr;
}
}
template <class Type>
void ImageVariable<Type>::removeLinks()
{
- if (m_linkPrevious)
- {
- // there is something before us, link it to the item after, or 0 if none
- m_linkPrevious->m_linkNext = m_linkNext;
- }
- if (m_linkNext)
- {
- // there is something after us, link it to the item before, or 0 if none
- m_linkNext->m_linkPrevious = m_linkPrevious;
- m_linkNext = 0;
- }
- m_linkPrevious = 0;
+ m_ptr.reset(new Type(*m_ptr));
}
template <class Type>
bool ImageVariable<Type>::isLinked() const
{
- // return true if there are any links, false if this variable is independant
- return (m_linkPrevious || m_linkNext);
+ return m_ptr.use_count() > 1;
}
template <class Type>
bool ImageVariable<Type>::isLinkedWith(const ImageVariable<Type> * otherVariable) const
{
// return true if we can find a link with the given item.
- return (searchBackwards(otherVariable) || searchForwards(otherVariable));
-}
-
-////////////////////////////////
-// Protected member functions //
-////////////////////////////////
-
-template <class Type>
-bool ImageVariable<Type>::searchBackwards(const ImageVariable<Type> * otherVariable) const
-{
- // is this what we are looking for?
- if (this == otherVariable) return true;
- // are there any more items to check?
- if (!m_linkPrevious) return false;
- // try another one.
- return m_linkPrevious->searchBackwards(otherVariable);
-}
-
-template <class Type>
-bool ImageVariable<Type>::searchForwards(const ImageVariable<Type> * otherVariable) const
-{
- // is this what we are looking for?
- if (this == otherVariable) return true;
- // are there any more items to check?
- if (!m_linkNext) return false;
- // try another one.
- return m_linkNext->searchForwards(otherVariable);
-}
-
-template <class Type>
-ImageVariable<Type> * ImageVariable<Type>::findStart()
-{
- // Is this the start of the list?
- if (!m_linkPrevious) return this;
- // look father back
- return m_linkPrevious->findStart();
-}
-
-template <class Type>
-ImageVariable<Type> * ImageVariable<Type>::findEnd()
-{
- // Is this the end of the list?
- if (!m_linkNext) return this;
- // look father forwards
- return m_linkNext->findEnd();
-}
-
-template <class Type>
-void ImageVariable<Type>::setBackwards(const Type data)
-{
- // set this and all proceeding items.
- m_data = data;
- if (m_linkPrevious) m_linkPrevious->setBackwards(data);
-}
-
-template <class Type>
-void ImageVariable<Type>::setForwards(const Type data)
-{
- // set this and all proceeding items.
- m_data = data;
- if (m_linkNext) m_linkNext->setForwards(data);
+ return m_ptr == otherVariable->m_ptr;
}
} // HuginBase namespace