Files
geant4/source/analysis/g4tools/include/tools/sg/holder
T
2020-12-04 12:30:43 +01:00

200 lines
4.8 KiB
Plaintext

// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_sg_holder
#define tools_sg_holder
// class to manage an object.
// Only one holder owns the object. In case
// of holder copy(), the new holder receives a null object.
#include "node"
#include "sf_string"
namespace tools {
namespace sg {
class base_holder : public node {
TOOLS_NODE(base_holder,tools::sg::base_holder,node)
public:
base_holder(const std::string& a_name):parent(),m_name(a_name) {}
virtual ~base_holder(){}
public:
base_holder(const base_holder& a_from):parent(a_from),m_name(a_from.m_name) {}
base_holder& operator=(const base_holder& a_from){
parent::operator=(a_from);
m_name = a_from.m_name;
return *this;
}
public:
const std::string& name() const {return m_name;}
protected:
std::string m_name;
};
template <class T>
class holder : public base_holder {
typedef base_holder parent;
public:
//WARNING : we do not put the T class name in the name of this class.
// We put it in the class_name field.
// We do that because of the bsg file format in order to be able
// to read back the object without having the T class around.
TOOLS_T_SCLASS(T,tools::sg::holder)
public:
virtual void* cast(const std::string& a_class) const {
if(void* p = cmp_cast< holder<T> >(this,a_class)) {return p;}
return parent::cast(a_class);
}
virtual node* copy() const {return new holder(*this);}
virtual const std::string& s_cls() const {return s_class();}
public:
sf_string class_name;
public:
virtual const desc_fields& node_desc_fields() const {
TOOLS_FIELD_DESC_NODE_CLASS(tools::sg::holder)
static const desc_fields s_v(parent::node_desc_fields(),1, //WARNING : take care of count.
TOOLS_ARG_FIELD_DESC(class_name)
);
return s_v;
}
private:
void add_fields(){
add_field(&class_name);
}
public:
holder(T* a_obj = 0,const std::string& a_name = "",bool a_own=true)
:parent(a_name)
,class_name(T::s_class())
,m_obj(a_obj) //it takes a_obj ownership.
,m_own(a_own)
{
add_fields();
}
virtual ~holder(){if(m_own) delete m_obj;}
public:
//any copy of a holder does NOT own any object (and we empty the name).
holder(const holder& a_from)
:parent(a_from)
,class_name(std::string())
,m_obj(0)
,m_own(false)
{
parent::m_name.clear();
add_fields();
}
holder& operator=(const holder& a_from){
parent::operator=(a_from);
class_name.value().clear();
m_obj = 0;
m_own = false;
parent::m_name.clear();
return *this;
}
public:
const T* object() const {return m_obj;}
T* object() {return m_obj;}
protected:
T* m_obj;
bool m_own;
};
template <class T>
inline holder<T>* cast_holder(node& a_node) {
typedef holder<T> h_t;
h_t* _h = (h_t*)a_node.cast(h_t::s_class());
if(!_h) return 0;
return (_h->class_name.value()==T::s_class()?_h:0);
}
template <class T>
inline const holder<T>* cast_holder(const node& a_node) {
typedef holder<T> h_t;
h_t* _h = (h_t*)a_node.cast(h_t::s_class());
if(!_h) return 0;
return (_h->class_name.value()==T::s_class()?_h:0);
}
template <class T>
inline const T* cast_holder_object(const node& a_node) {
typedef holder<T> h_t;
h_t* _h = (h_t*)a_node.cast(h_t::s_class());
if(!_h) return 0;
return (_h->class_name.value()==T::s_class()?_h->object():0);
}
template <class T>
inline T* cast_holder_object(node& a_node) {
typedef holder<T> h_t;
h_t* _h = (h_t*)a_node.cast(h_t::s_class());
if(!_h) return 0;
return (_h->class_name.value()==T::s_class()?_h->object():0);
}
template <class T>
inline void remove_holders(std::vector<node*>& a_vec){
typedef holder<T> h_t;
std::vector<node*>::iterator it;
for(it=a_vec.begin();it!=a_vec.end();) {
if(h_t* h = cast_holder<T>(*(*it))){
it = a_vec.erase(it);
delete h;
continue;
}
++it;
}
}
template <class T>
inline void remove_holders(std::vector<node*>& a_vec,const std::string& a_name){
typedef holder<T> h_t;
std::vector<node*>::iterator it;
for(it=a_vec.begin();it!=a_vec.end();) {
if(h_t* h = cast_holder<T>(*(*it))){
if(h->name()==a_name) {
it = a_vec.erase(it);
delete h;
continue;
}
}
++it;
}
}
template <class T>
inline T* find_holder(std::vector<node*>& a_vec,const std::string& a_name) {
//return the first named found.
typedef holder<T> h_t;
std::vector<node*>::iterator it;
for(it=a_vec.begin();it!=a_vec.end();++it) {
if(h_t* h = cast_holder<T>(*(*it))){
if(h->name()==a_name) return h->object();
}
}
return 0;
}
template <class T>
inline T* find_first_holder(std::vector<node*>& a_vec){
//return the first T found.
typedef holder<T> h_t;
std::vector<node*>::iterator it;
for(it=a_vec.begin();it!=a_vec.end();++it) {
if(h_t* h = cast_holder<T>(*(*it))) return h->object();
}
return 0;
}
}}
#endif