summaryrefslogtreecommitdiffstats
path: root/src/ml/dlib/dlib/reference_counter/reference_counter_kernel_1.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/ml/dlib/dlib/reference_counter/reference_counter_kernel_1.h')
-rw-r--r--src/ml/dlib/dlib/reference_counter/reference_counter_kernel_1.h298
1 files changed, 298 insertions, 0 deletions
diff --git a/src/ml/dlib/dlib/reference_counter/reference_counter_kernel_1.h b/src/ml/dlib/dlib/reference_counter/reference_counter_kernel_1.h
new file mode 100644
index 000000000..64e465550
--- /dev/null
+++ b/src/ml/dlib/dlib/reference_counter/reference_counter_kernel_1.h
@@ -0,0 +1,298 @@
+// Copyright (C) 2003 Davis E. King (davis@dlib.net)
+// License: Boost Software License See LICENSE.txt for the full license.
+#ifndef DLIB_REFERENCE_COUNTER_KERNEl_1_
+#define DLIB_REFERENCE_COUNTER_KERNEl_1_
+
+#include "reference_counter_kernel_abstract.h"
+#include "../algs.h"
+
+namespace dlib
+{
+
+ template <
+ typename T,
+ typename copy = copy_functor<T>
+ >
+ class reference_counter_kernel_1
+ {
+
+ /*!
+ INITIAL VALUE
+ *data = item of type T with its initial value
+ *count = 1
+
+ CONVENTION
+ *data = pointer to item of type T
+ *count = number of references to *data
+
+ if clear() threw an exception then count = 0 and data is not a
+ valid pointer
+ !*/
+
+ public:
+
+ typedef T type;
+
+
+ reference_counter_kernel_1 (
+ );
+
+ inline reference_counter_kernel_1 (
+ const reference_counter_kernel_1& item
+ );
+
+ virtual ~reference_counter_kernel_1 (
+ );
+
+ void clear (
+ );
+
+ T& modify (
+ );
+
+ inline const T& access (
+ ) const;
+
+ inline reference_counter_kernel_1& operator= (
+ const reference_counter_kernel_1& rhs
+ );
+
+ inline void swap (
+ reference_counter_kernel_1& item
+ );
+
+
+ private:
+
+ T* data;
+ unsigned long* count;
+ mutable copy copy_item;
+ };
+
+ template <
+ typename T,
+ typename copy
+ >
+ inline void swap (
+ reference_counter_kernel_1<T,copy>& a,
+ reference_counter_kernel_1<T,copy>& b
+ ) { a.swap(b); }
+
+// ----------------------------------------------------------------------------------------
+// ----------------------------------------------------------------------------------------
+ // member function definitions
+// ----------------------------------------------------------------------------------------
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename T,
+ typename copy
+ >
+ reference_counter_kernel_1<T,copy>::
+ reference_counter_kernel_1 (
+ )
+ {
+ data = new T;
+ try { count = new unsigned long; }
+ catch (...) { delete data; throw; }
+
+ *count = 1;
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename T,
+ typename copy
+ >
+ reference_counter_kernel_1<T,copy>::
+ reference_counter_kernel_1 (
+ const reference_counter_kernel_1<T,copy>& item
+ ) :
+ data(item.data),
+ count(item.count)
+ {
+ ++(*count);
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename T,
+ typename copy
+ >
+ reference_counter_kernel_1<T,copy>::
+ ~reference_counter_kernel_1 (
+ )
+ {
+ if (*count > 1)
+ {
+ // if there are other references to this data
+ --(*count);
+ }
+ else
+ {
+ // if there are no other references to this data
+ delete count;
+ delete data;
+ }
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename T,
+ typename copy
+ >
+ void reference_counter_kernel_1<T,copy>::
+ clear (
+ )
+ {
+ // if an exception was thrown last time clear() was called then do this
+ if (count == 0)
+ {
+ data = new T;
+ try { count = new unsigned long; }
+ catch (...) { delete data; throw; }
+
+ *count = 1;
+ }
+ // if there are other references to the data then do this
+ else if (*count > 1)
+ {
+ --(*count);
+
+ try { data = new T; }
+ catch (...) { count = 0; throw; }
+
+ try { count = new unsigned long; }
+ catch (...) { delete data; count = 0; throw; }
+
+ *count = 1;
+
+ }
+ else
+ {
+ // if there are no other references to this data
+ *count = 1;
+ delete data;
+ try { data = new T; } catch (...) { delete count; count = 0; throw; }
+ }
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename T,
+ typename copy
+ >
+ T& reference_counter_kernel_1<T,copy>::
+ modify (
+ )
+ {
+ // if this is not the only reference then make a new copy
+ if ( *count > 1 )
+ {
+ T& old_data = *data;
+ unsigned long& old_count = *count;
+
+
+ // get memory for the new copy
+ try { data = new T; }
+ catch (...) { data = &old_data; throw; }
+
+ try { count = new unsigned long; }
+ catch (...) {delete data; data = &old_data; count = &old_count; throw;}
+
+ // decrement the number of references to old_data
+ --(old_count);
+
+ *count = 1;
+
+ // make a copy of the old data
+ try { copy_item(old_data,*data); }
+ catch (...)
+ { delete data; delete count; data = &old_data; count = &old_count; }
+
+ }
+
+ return *data;
+
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename T,
+ typename copy
+ >
+ const T& reference_counter_kernel_1<T,copy>::
+ access (
+ ) const
+ {
+ return *data;
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename T,
+ typename copy
+ >
+ reference_counter_kernel_1<T,copy>& reference_counter_kernel_1<T,copy>::
+ operator= (
+ const reference_counter_kernel_1<T,copy>& rhs
+ )
+ {
+ if (this == &rhs)
+ return *this;
+
+ // delete the current data if this is the last reference to it
+ if (*count > 1)
+ {
+ // if there are other references to this data
+ --(*count);
+ }
+ else
+ {
+ // if there are no other references to this data
+ delete count;
+ delete data;
+ }
+
+ // copy the pointers
+ count = (rhs.count);
+ data = (rhs.data);
+ ++(*count);
+
+ return *this;
+
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename T,
+ typename copy
+ >
+ void reference_counter_kernel_1<T,copy>::
+ swap (
+ reference_counter_kernel_1<T,copy>& item
+ )
+ {
+ T* data_temp = data;
+ unsigned long* count_temp = count;
+
+ data = item.data;
+ count = item.count;
+
+ item.data = data_temp;
+ item.count = count_temp;
+ }
+
+// ----------------------------------------------------------------------------------------
+
+}
+
+#endif // DLIB_REFERENCE_COUNTER_KERNEl_1_
+