Commit e6d0981d authored by Ludovic Courtès's avatar Ludovic Courtès

core: Make 'ptr' and alias for 'std::shared_ptr'.

parent a87391c3
......@@ -276,13 +276,14 @@ function* plugins_manager::get_function(const arguments& args)
//Recursive call
function* f = get_function(temp_args);
if(dynamic_cast<nonlinear_function*>(f) == NULL)
nonlinear_function *nl_f = dynamic_cast<nonlinear_function*>(f);
if(nl_f == NULL)
{
std::cerr << "<<ERROR>> only non-linear functions are compatible with a compound" << std::endl;
}
else
{
compound->push_back(dynamic_cast<nonlinear_function*>(f), temp_args);
compound->push_back(ptr<nonlinear_function>(nl_f), temp_args);
}
}
......@@ -371,7 +372,9 @@ function* plugins_manager::get_function(const arguments& args)
std::cout << "<<DEBUG>> The lobe is fixed" << std::endl;
}
return new product_function(nl_func, func_fres, lobe_is_fixed, fresnel_is_fixed);
return new product_function(ptr<nonlinear_function>(nl_func),
ptr<nonlinear_function>(func_fres),
lobe_is_fixed, fresnel_is_fixed);
}
else
{
......@@ -412,7 +415,7 @@ ptr<function> plugins_manager::get_function(const std::string& n)
#ifdef DEBUG
std::cout << "<<DEBUG>> using function provider in file \"" << n << "\"" << std::endl;
#endif
return myFunc();
return ptr<function>(myFunc());
}
else
{
......@@ -429,7 +432,7 @@ ptr<data> plugins_manager::get_data(const std::string& n, const arguments& args)
#ifdef DEBUG
std::cout << "<<DEBUG>> no data plugin specified, returning a vertical_segment loader" << std::endl;
#endif
return new vertical_segment();
return ptr<data>(new vertical_segment());
}
DataPrototype myData = open_library<DataPrototype>(n, "provide_data");
......@@ -438,12 +441,12 @@ ptr<data> plugins_manager::get_data(const std::string& n, const arguments& args)
#ifdef DEBUG
std::cout << "<<DEBUG>> using data provider in file \"" << n << "\"" << std::endl;
#endif
return myData(args);
return ptr<data>(myData(args));
}
else
{
std::cerr << "<<ERROR>> no data provider found in file \"" << n << "\"" << std::endl;
return new vertical_segment() ;
return ptr<data>(new vertical_segment()) ;
}
}
ptr<fitter> plugins_manager::get_fitter(const std::string& n)
......@@ -462,7 +465,7 @@ ptr<fitter> plugins_manager::get_fitter(const std::string& n)
#ifdef DEBUG
std::cout << "<<DEBUG>> using fitter provider in file \"" << n << "\"" << std::endl;
#endif
return myFitter();
return ptr<fitter>(myFitter());
}
else
{
......@@ -496,7 +499,7 @@ void plugins_manager::check_compatibility( ptr<data>& d,
{
std::cout << "<<INFO>> has to change the parametrization of the input data " << params::get_name(d->input_parametrization()) << std::endl;
std::cout << "<<INFO>> to " << params::get_name(f->input_parametrization()) << std::endl;
ptr<data_params> dd = new data_params(d, f->input_parametrization());
ptr<data_params> dd = ptr<data_params>(new data_params(d, f->input_parametrization()));
d = dynamic_pointer_cast<data>(dd) ;
}
else
......
......@@ -12,191 +12,16 @@
#pragma once
/*! \class ptr
*
* Define a shared pointer class for automatic memory cleaning
* when dealing with objects created by plugins. All plugins should
* provide a ptr<object> instead of a object* so that the user won't
* have to worry about allocation/deallocation.
*
* ALTA provide a weak implementation of the ptr class. If a C++11
* compatible is used, it will try to use the STL version of shared
* pointer.
* Provide an alias for C++11's std::shared_ptr. Once upon a time this file
* contained a custom implementation of shared pointers.
*/
/* Checking for the presence of C++11 features like smart pointers. There
* is no clean way to do it for all compilers. This method is supposed to
* work with CLANG and GCC.
*
* See htpp://stackoverflow.com/questions/11886288/
*/
#if defined(USE_BOOST)
#include <boost/shared_ptr.hpp>
#define ptr boost::shared_ptr
#define dynamic_pointer_cast boost::dynamic_pointer_cast
#elif defined(TODO)
//__cplusplus >= 201103L
#include <memory>
template<class T> using ptr = std::shared_ptr<T>;
template<class T, class U>
inline ptr<U> dynamic_pointer_cast(const ptr<T>& ptr_t) {
return std::dynamic_pointer_cast<U>(ptr_t);
}
#else
#include <cstdlib> /* for 'NULL' */
/* Define a counter class. This class should not be used by any other part of
* ALTA code.
*/
struct ptr_counter
{
ptr_counter() : _count(1) { }
inline void increment()
{
++_count;
}
inline void decrement()
{
--_count;
}
inline unsigned int value() const
{
return _count;
}
unsigned int _count;
};
template<class T> class ptr;
/* Work around a bug in GCC 4.4.6 (and presumably older versions) whereby the
template parameters need to be given in reverse order. Failing to do that,
GCC fails with "no matching function for call to
'dynamic_pointer_cast(ptr<function>&)'", and similar errors. */
# if defined __GNUC__ && \
((__GNUC__ == 4 && __GNUC_MINOR__ <= 4) || (__GNUC__ < 4))
template<class U, class T>
# else
template<class T, class U>
# endif
ptr<U> dynamic_pointer_cast(const ptr<T>& ptr_t);
template<class T> class ptr
inline ptr<U> dynamic_pointer_cast(const ptr<T>& ptr_t)
{
public:
//! Empty constructor
ptr(T* ptr) : _ptr(ptr)
{
_counter = new ptr_counter();
}
//! Counter copy constructor
ptr(T* ptr, ptr_counter* counter) : _ptr(ptr), _counter(counter)
{
_counter->increment();
}
//! Copy constructor
ptr(const ptr<T>& p) : _ptr(p._ptr), _counter(p._counter)
{
_counter->increment();
}
//! Destructor, should free memory when the counter goes
//! to zero.
~ptr()
{
_counter->decrement();
if(_counter->value() < 1 || _ptr == NULL)
{
delete _ptr;
_ptr = NULL;
delete _counter;
_counter = NULL;
}
}
//! Evaluation operator. This operator should be inlined for
//! performance reasons.
inline T* operator-> () const
{
return _ptr;
}
//! Assignment operator. If a valid pointer is already present, its
//! counter is decremented and the pointer and counter might be
//! deleted in case the counter reach zero. Then, the elements of
//! a, both counter and pointer, are copied to this and the counter
//! is incremented.
ptr<T>& operator=(const ptr<T>& a)
{
//RP: Check and avoid assignment to itself
if((void*) this == (void *) &a)
{
return *this;
}
_counter->decrement();
if(_counter->value() < 1)
{
delete _ptr;
_ptr = NULL;
delete _counter;
_counter = NULL;
}
_counter = a._counter;
_ptr = a._ptr;
_counter->increment();
return *this;
}
//! Raw acces to the pointer. It is sometimes needed to
inline T* get() const
{
return _ptr;
}
//! Is the underlying pointer not NULL.
inline operator bool() const
{
return _ptr != NULL;
}
template<class U>
friend ptr<U> dynamic_pointer_cast(const ptr<T>& ptr_t)
{
U* u = dynamic_cast<U*>(ptr_t._ptr);
if(u == NULL)
{
return ptr<U>(NULL);
}
else
{
ptr<U> ptr_u = ptr<U>(u, ptr_t._counter);
return ptr_u;
}
}
private:
T* _ptr;
ptr_counter* _counter;
};
#endif
return std::dynamic_pointer_cast<U>(ptr_t);
}
/* ALTA --- Analysis of Bidirectional Reflectance Distribution Functions
Copyright (C) 2014 Inria
Copyright (C) 2014, 2015 Inria
This file is part of ALTA.
......@@ -25,17 +25,6 @@
#define bp boost::python
/* The following code register ALTA's shared pointer as a valid shared ptr
* to be used by boost::python .
*/
template <typename T> T* get_pointer(ptr<T>& p) {
return const_cast<T*>(p.get());
}
template <typename T> const T* get_pointer(const ptr<T>& p) {
return p.get();
}
namespace boost {
namespace python {
......@@ -195,10 +184,10 @@ ptr<function> get_function_from_args(const python_arguments& args) {
* The file is supposed to load the function correctly.
*/
ptr<function> load_function(const std::string& filename) {
return plugins_manager::load_function(filename);
return ptr<function>(plugins_manager::load_function(filename));
}
ptr<function> load_function_with_args(const std::string& filename, const arguments&) {
return plugins_manager::load_function(filename);
return ptr<function>(plugins_manager::load_function(filename));
}
/* Loading a function object from file
......
......@@ -112,8 +112,8 @@ int main(int argc, char** argv)
fit->set_parameters(args) ;
ptr<function> f = plugins_manager::get_function(args);
ptr<data> d = plugins_manager::get_data(args["data"], args);
ptr<function> f = ptr<function>(plugins_manager::get_function(args));
ptr<data> d = ptr<data>(plugins_manager::get_data(args["data"], args));
try
{
......
......@@ -459,7 +459,7 @@ main(int argc, char* argv[])
}
std::cout << "<<INFO>> Loading data ..." << std::endl;
ptr<vertical_segment> vs_data = new vertical_segment();
ptr<vertical_segment> vs_data = ptr<vertical_segment>(new vertical_segment());
//ptr<data> vs_data = plugins_manager::get_data("vertical_segment");
timer t;
......@@ -482,7 +482,7 @@ main(int argc, char* argv[])
// Load a function file representing the BRDF
ptr<function> brdf = plugins_manager::load_function(args["brdf"]) ;
ptr<function> brdf = ptr<function>(plugins_manager::load_function(args["brdf"]));
if(brdf.get() == NULL)
{
std::cout << "<<ERROR>> Could not load the BRDF. Check your file. ABORTING !!!! " << std::endl;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment