Метапрограммирование C++ doxygen документация

Я документирую некоторый код, который использует метапрограммирование в большой степени, например:

 template<rysq::type A, rysq::type B, rysq::type C, rysq::type D, class Transform>
 struct Kernel<meta::braket<A,B,C,D>, Transform,
               typename boost::enable_if<
                   quadrature<meta::braket<A,B,C,D>, Transform> >::type>
 : Eri <Transform> {

что хороший путь состоит в том, чтобы зарегистрировать такую конструкцию с помощью doxygen?

19
задан Anycorn 8 August 2010 в 17:03
поделиться

3 ответа

Использовать макросы препроцессора. Вот пример из еще неофициальной библиотеки Boost.XInt (сейчас стоит в очереди на рассмотрение для включения в Boost):

#ifdef BOOST_XINT_DOXYGEN_IGNORE
    // The documentation should see a simplified version of the template
    // parameters.
    #define BOOST_XINT_INITIAL_APARAMS ...
    #define BOOST_XINT_CLASS_APARAMS ...
    #define BOOST_XINT_CLASS_BPARAMS other
    #define BOOST_XINT_APARAMS ...
    #define BOOST_XINT_BPARAMS other
#else
    #define BOOST_XINT_INITIAL_APARAMS \
        class A0 = parameter::void_, \
        class A1 = parameter::void_, \
        class A2 = parameter::void_, \
        class A3 = parameter::void_, \
        class A4 = parameter::void_, \
        class A5 = parameter::void_
    #define BOOST_XINT_CLASS_APARAMS class A0, class A1, class A2, class A3, \
        class A4, class A5
    #define BOOST_XINT_APARAMS A0, A1, A2, A3, A4, A5
    #define BOOST_XINT_CLASS_BPARAMS class B0, class B1, class B2, class B3, \
        class B4, class B5
    #define BOOST_XINT_BPARAMS B0, B1, B2, B3, B4, B5
#endif

Используйте имена макросов #define d вместо параметры шаблона, везде, где они вам нужны, например:

/*! \brief The integer_t class template.

This class implements the standard aribitrary-length %integer type.

[...lots more documentation omitted...]
*/
template<BOOST_XINT_INITIAL_APARAMS>
class integer_t: virtual public detail::integer_t_data<BOOST_XINT_APARAMS>,
    public detail::nan_functions<detail::integer_t_data<BOOST_XINT_APARAMS>::
    NothrowType::value, // ...lots more base classes omitted...
{
    // ...etcetera

И поместите такие строки в Doxyfile:

PREDEFINED             = BOOST_XINT_DOXYGEN_IGNORE

EXPAND_AS_DEFINED      = BOOST_XINT_INITIAL_APARAMS \
                         BOOST_XINT_CLASS_APARAMS \
                         BOOST_XINT_CLASS_BPARAMS \
                         BOOST_XINT_APARAMS \
                         BOOST_XINT_BPARAMS

В результате Doxygen видит либо "...", либо "другое" для параметров шаблона, а компилятор видит настоящие. Если вы описываете параметры шаблона в документации для самого класса, то пользователю библиотеки нужно будет увидеть их только в одном месте, где он, вероятно, будет их искать; они будут спрятаны повсюду.

В качестве дополнительного преимущества этого дизайна, если вам когда-либо понадобится внести изменения в списки параметров шаблона, вам нужно будет изменить их только в определениях макросов и функциях, которые фактически используют измененные параметры. Все остальное адаптируется автоматически.

8
ответ дан 30 November 2019 в 05:11
поделиться

Мета-программирование, похоже, реализует математику. Я бы написал в документации doxygen описание математических формул с латексными эскейпами.

0
ответ дан 30 November 2019 в 05:11
поделиться

Вот мой взгляд на это:

///
/// \defgroup Kernel Kernel
///
/// \brief Kernel does this and that
/// \{

/// \brief Kernel template class brief description.
template<Braket,Transform,Boolean>
struct Kernel
{};

/// \brief Kernel partial template specialization brief description.
///
/// More detailed description...<br>
/// Partially specializes Kernel with meta::braket<A,B,C,D\>.<br>
/// If quadrature<meta::braket<A,B,C,D\>, Transform\> is true then enable
/// this algorithm, otherwise enable this other algorithm.<br>
/// Inherits privately from template class Eri<Transform\><br>
/// \tparam A           template parameter A of type rysq::type, documentation and concepts
/// \tparam B           template parameter B of type rysq::type, documentation and concepts
/// \tparam C           template parameter C of type rysq::type, documentation and concepts
/// \tparam D           template parameter D of type rysq::type, documentation and concepts
/// \tparam Transform   template parameter class Transform documentation and concepts
/// \see Kernel\<Braket,Transform,Boolean\>
/// \see Eri
/// \see meta::braket
/// \see quadrature
#ifdef DOXY
// This is the documentation version
template<A,B,C,D,Transform>
struct Kernel<Braket,Transform,Boolean>
#else
// This is what gets compiled
template<rysq::type A, rysq::type B, rysq::type C, rysq::type D, class Transform>
struct Kernel<meta::braket<A,B,C,D>, Transform,typename boost::enable_if<quadrature<meta::braket<A,B,C,D>, Transform> >::type>
#endif
: Eri <Transform> {};

/// \}

Не забудьте добавить DOXY в раздел PREDEFINED препроцессора Doxygen.

Обычно я предпочитаю скрывать детали реализации от пользователя моего кода, поэтому я меняю то, что видит Doxygen. В этом случае вы найдете все свои специализации в одной группе, группе ядра, а в списке классов все специализации будут сгруппированы вместе и не будут иметь очень длинного и непонятного названия.

Надеюсь, это поможет.

4
ответ дан 30 November 2019 в 05:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: