En bref: je souhaite extraire diverses options à partir de parameters de modèles variadiques, mais pas uniquement par balise, mais par index pour ces parameters, qui n’ont pas de balise connue . J’aime l’approche en boost (par exemple, les politiques de tas ou lockfree ), mais je veux la rendre compatible avec les conteneurs STL – le paramètre allocateur.
J’écris actuellement un modèle de queue / tampon d’enregistrements / objects de taille variable avec cette signature:
// current: template <typename R = byte, class Alloc = std::allocator, class... Opts> class rqueue; // what I want: template class rqueue;
J’ai quelques autres options possibles que j’ai décrites comme ceci:
namespace tag { struct allocator {}; ///< specify allocator for data storage struct virtual_offset {}; ///< manage offset in virtual memory struct fill_empty {}; ///< fill empty space (security or reconstruction) struct reconstructible {}; ///< fill empty and leave one slot between wp&rp } namespace opt { /// allocator for data storage template struct allocator: tag::allocator { typedef Alloc type; }; /// type for offset in virtual memory template struct virtual_offset: tag::virtual_offset { typedef Off type; }; /// type and value to fill empty space template struct fill_empty: tag::fill_empty { typedef T type; static constexpr T value = V; }; /// make state pointers reconstructible by leaving one slot between wp&rp template struct reconstructible : tag::reconstructible, fill_empty {}; }
// basic queue for custom record class rqueue; // advanced record storage that can be written to a file and reconstructed back rqueue<opt::virtual_offset, opt::reconstructible>; // specialization for ssortingngs with custom allocator rqueue; // alternative to above rqueue<const char*, opt::allocator>;
namespace opt { template struct bind { template static constexpr bool has() { return false; } template using get = Default; }; template struct bind { private: template static constexpr bool first() { return std::is_same::value || std::is_base_of::value; } template struct get_ { typedef typename bind::template get type; }; template struct get_ { typedef First type; }; public: template static constexpr bool has() { return first() || bind::template has(); } template using get = typename get_<Tag, Default, first()>::type; }; }
Il n’est pas aussi avancé que la bibliothèque de parameters Boost , mais effectue le travail … jusqu’à présent, avec la liste des parameters requirejs non étiquetés et des parameters facultatifs étiquetés.
cout << boolalpha; typedef opt::bind< opt::virtual_offset, opt::reconstructible > opts; cout << opts::has() << endl; cout << opts::has() << endl; cout << opts::has() << endl; cout << typeid(opts::get::type).name() << endl; cout << typeid(opts::get::type).name() << endl; cout << (int)opts::get::value << endl; typedef opt::bind no; cout << no::has() << endl; cout << no::has() << endl; cout << no::has() << endl; cout << typeid(no::get).name() << endl; typedef opt::bind<opt::fill_empty> one; cout << one::has() << endl; cout << one::has() << endl; cout << one::has() << endl; cout << typeid(one::get).name() << endl;
Je cherchais dans la bibliothèque de métaprogrammations / parameters de boost complexes et metafunctions
terminais par des metafunctions
qui peuvent faire le même travail que mon petit assistant (et bien plus, bien plus), mais je n’ai trouvé aucune solution pour extraire des options non étiquetées par index.
Peut-être devrais-je tout simplement oublier et coller avec ces balises, ou écrire une aide complexe pour filtrer toutes les options étiquetées et accéder à celles laissées par index … Mais avant de me rendre ou d’aller au bout du chemin, voici un bel endroit où demander: )
Remarque: Si vous vous référez à une bibliothèque, laissez une description de son utilisation, s’il vous plaît. Je vous remercie.
(spécialisation de l’assistant d’options déjà présenté, fusion avec le code d’origine)
template struct tags { template static constexpr bool match() { return false; }}; template struct tags { template static constexpr bool match() { return std::is_same::value || std::is_base_of::value || tags::template match
template class rqueue { // bind tags and options typedef opt::bind, Opts...> opts; public: // get first untagged option or byte if none typedef typename opts::template at<0,byte> value_type, record_type, *pointer, &reference; // get second untagged option, or allocator option or std::allocator typedef typename std::conditional< (opts::count > 1), typename opts::template at<1>, typename opts::template get>>::type allocator_type; //...shorter version of the above typedef typename opts::template at<1, typename opts::template get>> allocator_type_v2; // get type specified as virtual_offset or void typedef typename opts::template get>::type offset_type;