Mantid
Loading...
Searching...
No Matches
cow_ptr.h
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2007 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
7#pragma once
8
9#include "MultiThreaded.h"
10
11#ifndef Q_MOC_RUN
12#include <memory>
13#endif
14
15#include <mutex>
16#include <vector>
17
18namespace Mantid {
19namespace Kernel {
41template <typename DataType> class cow_ptr {
42public:
43 using ptr_type = std::shared_ptr<DataType>;
44 using value_type = DataType;
45
46private:
48 std::mutex copyMutex;
49
50public:
51 cow_ptr(ptr_type &&resourceSptr) noexcept;
52 cow_ptr(const ptr_type &resourceSptr) noexcept;
53 explicit cow_ptr(DataType *resourcePtr);
56 constexpr cow_ptr(std::nullptr_t) noexcept : Data(nullptr) {}
57 cow_ptr(const cow_ptr<DataType> &) noexcept;
58 // Move is hand-written, since std::mutex member prevents auto-generation.
59 cow_ptr(cow_ptr<DataType> &&other) noexcept : Data(std::move(other.Data)) {}
61 // Move is hand-written, since std::mutex member prevents auto-generation.
63 Data = std::move(rhs.Data);
64 return *this;
65 }
67
69 const DataType *get() const noexcept { return Data.get(); }
70
72 explicit operator bool() const noexcept { return bool(Data); }
73
76 long use_count() const noexcept { return Data.use_count(); }
77
80 bool unique() const noexcept { return Data.unique(); }
81
82 const DataType &operator*() const { return *Data; }
83 const DataType *operator->() const { return Data.get(); }
84 bool operator==(const cow_ptr<DataType> &A) const noexcept { return Data == A.Data; }
85 bool operator!=(const cow_ptr<DataType> &A) const noexcept { return Data != A.Data; }
86 DataType &access();
87};
88
93template <typename DataType> cow_ptr<DataType>::cow_ptr(DataType *resourcePtr) : Data(resourcePtr) {}
94
98template <typename DataType> cow_ptr<DataType>::cow_ptr() : Data(std::make_shared<DataType>()) {}
99
104// Note: Need custom implementation, since std::mutex is not copyable.
105template <typename DataType>
106cow_ptr<DataType>::cow_ptr(const cow_ptr<DataType> &A) noexcept : Data(std::atomic_load(&A.Data)) {}
107
114// Note: Need custom implementation, since std::mutex is not copyable.
115template <typename DataType> cow_ptr<DataType> &cow_ptr<DataType>::operator=(const cow_ptr<DataType> &A) noexcept {
116 if (this != &A) {
117 std::atomic_store(&Data, std::atomic_load(&A.Data));
118 }
119 return *this;
120}
121
128template <typename DataType> cow_ptr<DataType> &cow_ptr<DataType>::operator=(const ptr_type &A) noexcept {
129 if (this->Data != A) {
130 std::atomic_store(&Data, std::atomic_load(&A));
131 }
132 return *this;
133}
134
147template <typename DataType> DataType &cow_ptr<DataType>::access() {
148 // Use a double-check for sharing so that we only acquire the lock if
149 // absolutely necessary
150 if (!Data.unique()) {
151 std::lock_guard<std::mutex> lock{copyMutex};
152 // Check again because another thread may have taken copy and dropped
153 // reference count since previous check
154 if (!Data.unique()) {
155 std::atomic_store(&Data, std::make_shared<DataType>(*Data));
156 }
157 }
158 return *Data;
159}
160
161template <typename DataType> cow_ptr<DataType>::cow_ptr(ptr_type &&resourceSptr) noexcept {
162 std::atomic_store(&this->Data, std::move(resourceSptr));
163}
164
165template <typename DataType> cow_ptr<DataType>::cow_ptr(const ptr_type &resourceSptr) noexcept {
166 std::atomic_store(&this->Data, std::atomic_load(&resourceSptr));
167}
168
169} // NAMESPACE Kernel
170
172using MantidVec = std::vector<double>;
173
176
177} // NAMESPACE Mantid
const std::vector< double > & rhs
Implements a copy on write data template.
Definition: cow_ptr.h:41
bool operator!=(const cow_ptr< DataType > &A) const noexcept
Based on ptr inequality.
Definition: cow_ptr.h:85
constexpr cow_ptr(std::nullptr_t) noexcept
Constructs a cow_ptr with no managed object, i.e. empty cow_ptr.
Definition: cow_ptr.h:56
std::shared_ptr< DataType > ptr_type
typedef for the storage
Definition: cow_ptr.h:43
cow_ptr< DataType > & operator=(const ptr_type &) noexcept
Assignment operator : double references the data object maybe drops the old reference.
Definition: cow_ptr.h:128
const DataType * get() const noexcept
Returns the stored pointer.
Definition: cow_ptr.h:69
cow_ptr< DataType > & operator=(const cow_ptr< DataType > &) noexcept
Assignment operator : double references the data object maybe drops the old reference.
Definition: cow_ptr.h:115
DataType & access()
Access function.
Definition: cow_ptr.h:147
const DataType * operator->() const
indirectrion dereference access
Definition: cow_ptr.h:83
const DataType & operator*() const
Pointer dereference access.
Definition: cow_ptr.h:82
cow_ptr(const cow_ptr< DataType > &) noexcept
Copy constructor : double references the data object.
Definition: cow_ptr.h:106
cow_ptr(ptr_type &&resourceSptr) noexcept
Definition: cow_ptr.h:161
cow_ptr< DataType > & operator=(cow_ptr< DataType > &&rhs) noexcept
Definition: cow_ptr.h:62
bool unique() const noexcept
Checks if *this is the only shared_ptr instance managing the current object, i.e.
Definition: cow_ptr.h:80
long use_count() const noexcept
Returns the number of different shared_ptr instances (this included) managing the current object.
Definition: cow_ptr.h:76
cow_ptr()
Constructor : creates new data() object.
Definition: cow_ptr.h:98
DataType value_type
typedef for the data type
Definition: cow_ptr.h:44
ptr_type Data
Real object Ptr.
Definition: cow_ptr.h:47
std::mutex copyMutex
Definition: cow_ptr.h:48
bool operator==(const cow_ptr< DataType > &A) const noexcept
Based on ptr equality.
Definition: cow_ptr.h:84
cow_ptr(cow_ptr< DataType > &&other) noexcept
Definition: cow_ptr.h:59
cow_ptr(const ptr_type &resourceSptr) noexcept
Definition: cow_ptr.h:165
cow_ptr(DataType *resourcePtr)
Constructor : creates a new cow_ptr around the resource resource is a sink.
Definition: cow_ptr.h:93
Helper class which provides the Collimation Length for SANS instruments.
std::vector< double > MantidVec
typedef for the data storage used in Mantid matrix workspaces
Definition: cow_ptr.h:172
STL namespace.