Rechercher les options / parameters / arguments du modèle sans étiquette par position

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.

Préface

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 {}; } 

Usage

 // 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>; 

Assistant Pack d’options

 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.

Code de test

 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; 

Des questions

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.

  1. Est-ce que ça m’a manqué? Est-ce qu’il y a quelque part?
  2. Pouvez-vous me proposer une solution différente?

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.

J’ai réussi à le faire fonctionner

(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 

Usage

 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;