Mantid
Loading...
Searching...
No Matches
ExtractSharedPtr.h
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2015 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 <boost/python/extract.hpp>
10#include <boost/shared_ptr.hpp>
11#include <boost/weak_ptr.hpp>
12
14
15template <typename T> struct ExtractSharedPtr {
16 explicit ExtractSharedPtr(const boost::python::object &pyvalue) noexcept : ExtractSharedPtr<T>(pyvalue.ptr()) {}
17 explicit ExtractSharedPtr(PyObject *pyvalue) noexcept;
18 inline bool check() const noexcept { return m_value.get() != nullptr; }
19 const std::shared_ptr<T> operator()() const;
20
21private:
22 std::shared_ptr<T> m_value;
23};
24
29template <typename T> ExtractSharedPtr<T>::ExtractSharedPtr(PyObject *pyvalue) noexcept : m_value() {
30 // Here we assume we want to extract out an existing shared_ptr from a Python
31 // object if one exists. Naievly one would just do extract<std::shared_ptr<T>>
32 // but this will create a second shared_ptr managing the same resource and
33 // undefined behaviour when both come to try and delete the same object.
34 //
35 // The correct course of action is to extract a reference to shared_ptr<T>
36 // and this will fail if the object is not a shared_ptr. We also deal with
37 // the case where a weak_ptr may have been handed out by first trying to
38 // extract a reference to weak_ptr<T> and falling back to a reference to
39 // shared_ptr<T> if this fails.
40
41 using boost::python::extract;
42 if (extract<std::weak_ptr<T> &> extractWeakRef(pyvalue); extractWeakRef.check()) {
43 m_value = extractWeakRef().lock();
44 } else if (extract<std::shared_ptr<T> &> extractSharedRef(pyvalue); extractSharedRef.check()) {
45 m_value = extractSharedRef();
46 }
47}
48
52template <typename T> const std::shared_ptr<T> ExtractSharedPtr<T>::operator()() const {
53 if (check()) {
54 return m_value;
55 } else {
56 throw std::invalid_argument("Unable to extract shared_ptr from Python object");
57 }
58}
59
60} // namespace Mantid::PythonInterface
const std::string & m_value
Definition: Algorithm.cpp:71
const std::shared_ptr< T > operator()() const
ExtractSharedPtr(const boost::python::object &pyvalue) noexcept