-
Notifications
You must be signed in to change notification settings - Fork 122
/
TypedPropertyValueHandler.h
169 lines (156 loc) · 7.17 KB
/
TypedPropertyValueHandler.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#ifndef MANTID_PYTHONINTERFACE_TYPEDPROPERTYVALUEHANDLER_H_
#define MANTID_PYTHONINTERFACE_TYPEDPROPERTYVALUEHANDLER_H_
/**
Copyright © 2011 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory
This file is part of Mantid.
Mantid is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
Mantid is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
File change history is stored at: <https://github.com/mantidproject/mantid>
Code Documentation is available at: <http://doxygen.mantidproject.org>
*/
#include "MantidPythonInterface/kernel/Registry/PropertyValueHandler.h"
#include "MantidPythonInterface/kernel/IsNone.h" // includes object.hpp
#include "MantidKernel/PropertyWithValue.h"
#include "MantidKernel/IPropertyManager.h"
#include <boost/python/extract.hpp>
#include <boost/python/converter/arg_from_python.hpp>
#include <boost/weak_ptr.hpp>
#include <string>
namespace Mantid
{
namespace PythonInterface
{
namespace Registry
{
/**
* This class provides a templated class object that is able to take a
* python object and perform operations with a given C type.
*/
template<typename ValueType>
struct DLLExport TypedPropertyValueHandler : public PropertyValueHandler
{
/**
* Set function to handle Python -> C++ calls and get the correct type
* @param alg :: A pointer to an IPropertyManager
* @param name :: The name of the property
* @param value :: A boost python object that stores the value
*/
void set(Kernel::IPropertyManager* alg, const std::string &name, const boost::python::object & value)
{
alg->setProperty<ValueType>(name, boost::python::extract<ValueType>(value));
}
/**
* Create a PropertyWithValue from the given python object value
* @param name :: The name of the property
* @param defaultValue :: The defaultValue of the property. The object attempts to extract
* a value of type ValueType from the python object
* @param validator :: A python object pointing to a validator instance, which can be None.
* @param direction :: The direction of the property
* @returns A pointer to a newly constructed property instance
*/
Kernel::Property * create(const std::string & name, const boost::python::object & defaultValue,
const boost::python::object & validator, const unsigned int direction) const
{
using boost::python::extract;
const ValueType valueInC = extract<ValueType>(defaultValue)();
Kernel::Property *valueProp(NULL);
if( isNone(validator) )
{
valueProp = new Kernel::PropertyWithValue<ValueType>(name, valueInC, direction);
}
else
{
const Kernel::IValidator *propValidator = extract<Kernel::IValidator*>(validator);
valueProp = new Kernel::PropertyWithValue<ValueType>(name, valueInC, propValidator->clone(), direction);
}
return valueProp;
}
/// Is the given object a derived type of this objects Type
bool checkExtract(const boost::python::object & value) const
{
boost::python::extract<ValueType> extractor(value);
return extractor.check();
}
};
//
// Specialization for shared_ptr types that can be set via weak pointers
//
template<typename T>
struct DLLExport TypedPropertyValueHandler<boost::shared_ptr<T> > : public PropertyValueHandler
{
/// Convenience typedef
typedef T PointeeType;
/// Convenience typedef
typedef boost::shared_ptr<T> PropertyValueType;
/**
* Set function to handle Python -> C++ calls and get the correct type
* @param alg :: A pointer to an IPropertyManager
* @param name :: The name of the property
* @param value :: A boost python object that stores the value
*/
void set(Kernel::IPropertyManager* alg, const std::string &name, const boost::python::object & value)
{
using namespace boost::python;
typedef boost::weak_ptr<Kernel::DataItem> DataItem_wptr;
PropertyValueType sharedItem;
extract<DataItem_wptr> weakPtrExtractor(value);
if(weakPtrExtractor.check())
{
// NOTE: The type here must be DataItem not T as if it came from the ADS
// then that's what it was originally
// If we can extract a weak pointer then we must construct the shared pointer
// from the weak pointer itself to ensure the new shared_ptr has the correct
// use count
sharedItem = boost::dynamic_pointer_cast<PointeeType>(weakPtrExtractor().lock());
}
else
{
sharedItem = extract<PropertyValueType>(value)();
}
alg->setProperty<PropertyValueType>(name, sharedItem);
}
/**
* Create a PropertyWithValue from the given python object value
* @param name :: The name of the property
* @param defaultValue :: The defaultValue of the property. The object attempts to extract
* a value of type ValueType from the python object
* @param validator :: A python object pointing to a validator instance, which can be None.
* @param direction :: The direction of the property
* @returns A pointer to a newly constructed property instance
*/
Kernel::Property * create(const std::string & name, const boost::python::object & defaultValue,
const boost::python::object & validator, const unsigned int direction) const
{
using boost::python::extract;
const boost::shared_ptr<T> valueInC = extract<PropertyValueType>(defaultValue)();
Kernel::Property *valueProp(NULL);
if( isNone(validator) )
{
valueProp = new Kernel::PropertyWithValue<PropertyValueType>(name, valueInC, direction);
}
else
{
const Kernel::IValidator *propValidator = extract<Kernel::IValidator*>(validator);
valueProp = new Kernel::PropertyWithValue<PropertyValueType>(name, valueInC, propValidator->clone(), direction);
}
return valueProp;
}
/// Is the given object a derived type of this objects Type
bool checkExtract(const boost::python::object & value) const
{
boost::python::extract<PropertyValueType> extractor(value);
return extractor.check();
}
};
}
}
}
#endif /* MANTID_PYTHONINTERFACE_TYPEDPROPERTYVALUEHANDLER_H_ */