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
| #include <iostream>
#include <boost/any.hpp>
#include <boost/preprocessor.hpp>
#include <map>
// definitions des attributs:
#define SEQ_ATTRIBUTS \
( (E_1,int,12) ) \
( (E_2,char,'t') ) \
( (E_3,double,4.56) )
/*
********************************************************************************
******************** Implementation de la classe de configuration **********
********************************************************************************
*/
// creation de l'enumeration:
#define SEQ_AJOUT_ELEM_ENUM(r,data,elem)\
BOOST_PP_TUPLE_ELEM(3,0,elem),
// Enumeration des attributs:
enum E_Attributs
{
BOOST_PP_SEQ_FOR_EACH(SEQ_AJOUT_ELEM_ENUM,~,SEQ_ATTRIBUTS)
};
#undef SEQ_AJOUT_ELEM_ENUM
// classe de description des attributs:
template<E_Attributs> struct CTraitTypeAttribut{};
// macro pour leur specialisation
#define D_CREER_ATTRIBUT(r,data,Attribut)\
template<> struct CTraitTypeAttribut<BOOST_PP_TUPLE_ELEM(3,0,Attribut)>{\
typedef BOOST_PP_TUPLE_ELEM(3,1,Attribut) TypeAttribut;\
static const TypeAttribut Defaut;\
};\
const CTraitTypeAttribut<BOOST_PP_TUPLE_ELEM(3,0,Attribut)>::TypeAttribut CTraitTypeAttribut<BOOST_PP_TUPLE_ELEM(3,0,Attribut)>::Defaut = BOOST_PP_TUPLE_ELEM(3,2,Attribut);
BOOST_PP_SEQ_FOR_EACH(D_CREER_ATTRIBUT,~,SEQ_ATTRIBUTS)
#undef D_CREER_ATTRIBUT
// Macros pour preprocessor/repeat:
#define D_NOM_ATTRIBUT(Attribut) BOOST_PP_CAT(m_,BOOST_PP_TUPLE_ELEM(3,0,Attribut))
#define D_DECLARE_ATTRIBUT(r,data,Attribut)\
CTraitTypeAttribut<BOOST_PP_TUPLE_ELEM(3,0,Attribut)>::TypeAttribut D_NOM_ATTRIBUT(Attribut);
#define D_INITIALISE_ATTRIBUT(r,data,Attribut)\
D_NOM_ATTRIBUT(Attribut) = CTraitTypeAttribut<BOOST_PP_TUPLE_ELEM(3,0,Attribut)>::Defaut;
#define D_SPECIALISE_GETATTRIBUT(r,data,Attribut)\
template<> CTraitTypeAttribut<BOOST_PP_TUPLE_ELEM(3,0,Attribut)>::TypeAttribut& CConfigurationDefaut::GetAttribut<BOOST_PP_TUPLE_ELEM(3,0,Attribut)>()\
{return D_NOM_ATTRIBUT(Attribut);}
// class de configuration par défaut:
class CConfigurationDefaut
{
public:
// récupération de l'instance:
static CConfigurationDefaut&Defaut() {return m_Instance;}
// récupération d'un attribut:
template<E_Attributs P_Attr> typename CTraitTypeAttribut<P_Attr>::TypeAttribut& GetAttribut();
private:
// declaration des attributs:
BOOST_PP_SEQ_FOR_EACH(D_DECLARE_ATTRIBUT,~,SEQ_ATTRIBUTS)
private:
CConfigurationDefaut(){
// Initialisation des attributs:
BOOST_PP_SEQ_FOR_EACH(D_INITIALISE_ATTRIBUT,~,SEQ_ATTRIBUTS)
}
CConfigurationDefaut(const CConfigurationDefaut&){}
~CConfigurationDefaut(){}
CConfigurationDefaut&operator=(const CConfigurationDefaut&){return *this;}
static CConfigurationDefaut m_Instance;
};
// spécialisation partielle de l'accesseur aux attributs:
BOOST_PP_SEQ_FOR_EACH(D_SPECIALISE_GETATTRIBUT,~,SEQ_ATTRIBUTS)
CConfigurationDefaut CConfigurationDefaut::m_Instance;
#undef D_DECLARE_ATTRIBUT
#undef D_INITIALISE_ATTRIBUT
#undef D_SPECIALISE_GETATTRIBUT
// class de configuration partielle:
class CConfig
{
public:
template<enum E_Attributs P_Attribut>
typename CTraitTypeAttribut<P_Attribut>::TypeAttribut getAttribut() const
{
std::map<enum E_Attributs,boost::any>::const_iterator L_itElement;
L_itElement = m_mapAttributs.find(P_Attribut);
if(L_itElement!=m_mapAttributs.end()){
return boost::any_cast<typename CTraitTypeAttribut<P_Attribut>::TypeAttribut>(L_itElement->second);
}
return CConfigurationDefaut::Defaut().GetAttribut<P_Attribut>();
}
template<enum E_Attributs P_Attribut>
void setAttribut(const typename CTraitTypeAttribut<P_Attribut>::TypeAttribut&P_oNouvelleValeur)
{
std::map<enum E_Attributs,boost::any>::iterator L_itElement;
L_itElement = m_mapAttributs.find(P_Attribut);
if(L_itElement==m_mapAttributs.end()){
std::pair<std::map<enum E_Attributs,boost::any>::iterator,bool> L_eRetour;
L_eRetour = m_mapAttributs.insert(std::pair<enum E_Attributs,boost::any>(P_Attribut,P_oNouvelleValeur));
L_itElement = L_eRetour.first;
}
L_itElement->second = P_oNouvelleValeur;
}
template<enum E_Attributs P_Attribut>
static void setAttributDefaut(const typename CTraitTypeAttribut<P_Attribut>::TypeAttribut&P_oNouvelleValeur)
{
CConfigurationDefaut::Defaut().GetAttribut<P_Attribut>() = P_oNouvelleValeur;
}
private:
std::map<enum E_Attributs,boost::any> m_mapAttributs;
};
int main(int argc, char* argv[])
{
CConfig L_oConfig1;
CConfig L_oConfig2;
std::cout<<"Config 1/E_1: "<<L_oConfig1.getAttribut<E_1>()<<std::endl;
std::cout<<"Config 2/E_1: "<<L_oConfig2.getAttribut<E_1>()<<std::endl;
L_oConfig2.setAttribut<E_1>(3);
std::cout<<"Config 1/E_1: "<<L_oConfig1.getAttribut<E_1>()<<std::endl;
std::cout<<"Config 2/E_1: "<<L_oConfig2.getAttribut<E_1>()<<std::endl;
CConfig::setAttributDefaut<E_1>(-1);
std::cout<<"Config 1/E_1: "<<L_oConfig1.getAttribut<E_1>()<<std::endl;
std::cout<<"Config 2/E_1: "<<L_oConfig2.getAttribut<E_1>()<<std::endl;
std::getc(stdin);
return 0;
} |
Partager