// Copyright (C) 2010, Guy Barrand. All rights reserved. // See the file tools.license for terms. #ifndef tools_sg_bmf #define tools_sg_bmf // mf for multiple field. // bmf is intended to have no implementation of : // virtual bool write(io::iwbuf&) // virtual bool read(io::irbuf&) #include "field" namespace tools { namespace sg { template class bmf : public field { typedef field parent; public: static const std::string& s_class() { //we do not use stype(T()). static const std::string s_v("tools::sg::bmf"); return s_v; } virtual void* cast(const std::string& a_class) const { if(void* p = cmp_cast< bmf >(this,a_class)) {return p;} return parent::cast(a_class); } virtual const std::string& s_cls() const {return s_class();} public: bmf(){} bmf(const T& a_value) {m_values.push_back(a_value);} bmf(const std::vector& a_v) {m_values = a_v;} virtual ~bmf(){m_values.clear();} public: bmf(const bmf& a_from):parent(a_from),m_values(a_from.m_values){} bmf& operator=(const bmf& a_from){ parent::operator=(a_from); if(a_from.m_values!=m_values) m_touched = true; m_values = a_from.m_values; return *this; } public: bmf& operator=(const std::vector& a_from){ if(a_from!=m_values) m_touched = true; m_values = a_from; return *this; } bool operator==(const bmf& a_from) const { return m_values==a_from.m_values; } bool operator!=(const bmf& a_from) const { return !operator==(a_from); } const T& operator[](size_t a_index) const { //WARNING : no check is done on a_index. return m_values[a_index]; } T& operator[](size_t a_index) { //WARNING : no check is done on a_index. return m_values[a_index]; } public: size_t size() const {return m_values.size();} bool empty() const {return m_values.empty();} const std::vector& values() const {return m_values;} std::vector& values() {return m_values;} void add(const T& a_value) { m_values.push_back(a_value); m_touched = true; } void add(const std::vector& a_vals) { if(a_vals.empty()) return; typedef typename std::vector::const_iterator const_it_t; for(const_it_t it=a_vals.begin();it!=a_vals.end();++it){ m_values.push_back(*it); } m_touched = true; } void add_allocated(size_t& a_pos,const T& a_1,const T& a_2,const T& a_3) { //used in sg::plotter. std::vector& v = m_values; v[a_pos] = a_1;a_pos++; v[a_pos] = a_2;a_pos++; v[a_pos] = a_3;a_pos++; m_touched = true; } typedef typename std::vector::iterator it_t; void insert(const it_t& a_it,const T& a_value) { m_values.insert(a_it,a_value); m_touched = true; } bool set_value(size_t a_index,const T& a_value) { if(a_index>=m_values.size()) return false; if(m_values[a_index]!=a_value) m_touched = true; m_values[a_index] = a_value; return true; } bool get_value(size_t a_index,T& a_value) { if(a_index>=m_values.size()) {a_value=T();return false;} a_value = m_values[a_index]; return true; } void clear() { if(m_values.size()) m_touched = true; m_values.clear(); } void set_values(const std::vector& a_values) { if(a_values!=m_values) m_touched = true; m_values = a_values; } void set_value(const T& a_value) { //used in ArcheryTune. bool to_resize = m_values.size()==1?false:true; bool is_eq = ( (m_values.size()>=1) && (m_values[0]==a_value) ) ? true : false; if(to_resize) m_values.resize(1); if(to_resize || !is_eq) m_touched = true; m_values[0] = a_value; } public: //for iv2sg bool setValues(size_t a_index,size_t a_num,const T* a_vs) { // 012345678 // 234 if((a_index+a_num)>=m_values.size()) m_values.resize(a_index+a_num); for(size_t index=0;index=m_values.size()) m_values.resize(a_index+1); if(m_values[a_index]!=a_value) m_touched = true; m_values[a_index] = a_value; return true; } bool setValue(const T& a_value) {set_value(a_value);return true;} bmf& operator=(const T& a_v){ if(!setValue(a_v)) {} return *this; } size_t getNum() const {return m_values.size();} T* getValues(size_t a_start) { //for gopaw. if(a_start>=(m_values.size()+1)) return 0; T* data = m_values.data(); return data+a_start; } protected: std::vector m_values; }; }} #endif