Doxygen: arguments and methods with the same names - doxygen

I wanted to ask if anybody knows how to prevent doxygen producing links to methods from function arguments with the same name.
For example: in this documentation, QModelIndex buddy (const QModelIndex &index) the index argument is made into a link to the totally unrelated index(int row, int column, const QModelIndex &parent) method. Do you know how to prevent this?
The links are auto-generated so I can't use the % in front:
My code:
In the header:
QModelIndex buddy(const QModelIndex &index) const override;
In the source:
/*!
\reimp
*/
QModelIndex TransposeProxyModel::buddy(const QModelIndex &index) const
{/*some implementation*/}
If it matters, \reimp is an alias defined as reimp=Reimplemented from base class

Related

Accessing private member values with external template function

I'm a noob of c++, I'm trying to use a template function to get the private members inside a class because there are two types of parameters.
What I wrote is like:
template <typename Type>
Type const& Get(Type const& value)
{
return value;
}
class Event{
public:
Event(int const InputYear, int const InputMonth, int const InputDay, char const* InputContent, char const* InputNa me = "None")
:Year(InputYear), Month(InputMonth), Day(InputDay), Content(InputContent), Name(InputName)
{
}
~Event();
private:
int Year;
int Month;
int Day;
char* Content;
char* Name;
friend Type const& Get(Type const& value);
};
I don't know if my definition of friend is correct, if not could someone tell me how to use such template to access the private members?
The specification tells us that under certain circumstances (in this case explicit template instantiations), the usual access checking rules are not applied.
12 The usual access checking rules do not apply to names used to specify explicit instantiations. [ Note: In
particular, the template arguments and names used in the function declarator (including parameter types,
return types and exception specifications) may be private types or objects which would normally not be
accessible and the template may be a member template or member function which would not normally be
accessible. — end note ]
Thus, we can use this property to make a generic getter to a private member.
template <auto Event::* Member>
struct Getter {
friend auto &get(Event &e) { return e.*Member; }
};
template struct Getter<&Event::Year>;
auto &get(Event &e);
Event event{2021, 12, 24, "some event description"};
int year = get(event); // 2021

Systemverilog const ref arg position when constructing an object

I am creating a class that needs a reference to the test bench's configuration object. Since the configuration must be intact throughout the simulation, I pass it as a const ref object. Here is a sudo code that I want to run:
class tb_config;
int unsigned rate;
int unsigned chnls[];
const int unsigned nb_chnls;
function new (int unsigned rate, int unsigned nb_chnls);
this.rate = rate;
this.nb_chnls = nb_chnls;
chnls = new[nb_chnls];
endfunction
endclass
class tx_phy;
static int phy_id;
tb_config cfg;
function new (int unsigned phy_id, const ref tb_config cfg);
this.phy_id = phy_id;
this.cfg = cfg;
endfunction
endclass
module test;
tb_config cfg = new(100, 4);
tx_phy phy = new( 1234, cfg);
endmodule
The code above works perfectly fine and it meets my expectation. But if I change the arguments in tx_phy::new to function new (const ref tb_config cfg, int unsigned phy_id); and pass the values to the constructor accordingly I get the following error in Cadence Incisive:
invalid ref argument usage because actual argument is not a variable.
Also same thing happens when I test it with Aldec in edaplayground: https://www.edaplayground.com/x/5PWV
I assume this is a language limitation, but is there any other reason for that??
The reason for this is because the argument kind is implicit if not specified. You specified const ref for the first argument, but nothing for the second argument, so it is also implicitly const ref. Adding input to the second argument declaration fixes this.
function new (const ref tb_config cfg, input int unsigned phy_id);
I also want to add const ref tb_config cfg is equivalent to writing
function new (tb_config cfg, int unsigned phy_id);
Both of these arguments are implicitly input arguments, which means they are copied upon entry.
A class variable is already a reference. Passing a class variable by ref means that you can update the handle the class variable has from within the function. Making the argument a const ref means you will not be able to update the class variable, but you can still update members of the class the variable references. There is no mechanism to prevent updating members of class object if you have a handle to it other than by declaring them protected or local.
The only place it makes sense to pass function arguments by ref in SystemVerilog is as an optimization when the arguments are large data structures like an array, and you only need to access a few of the elements of the array. You can use task ref arguments when the arguments need to be updated during the lifetime of the task (i.e. passing a clock as an argument).

Using boost::program_options with own template class possible?

I'm currently start using boost::program_options for parsing command line options as well as configuration files.
Is it possible to use own template classes as option arguments? That means, something like
#include <iostream>
#include "boost/program_options.hpp"
namespace po = boost::program_options;
template <typename T>
class MyClass
{
private:
T* m_data;
size_t m_size;
public:
MyClass( size_t size) : m_size(size) { m_data = new T[size]; }
~MyClass() { delete[] m_data; }
T get( size_t i ) { return m_data[i]; }
void set( size_t i, T value ) { m_data[i] = value; }
};
int main (int argc, const char * argv[])
{
po::options_description generic("General options");
generic.add_options() ("myclass", po::value< MyClass<int>(2) >(),
"Read MyClass");
return 0;
}
Trying to compile this I get an Semantic Issue (No matching function for call to 'value'). I guess I need to provide some casting to an generalized type but I have no real idea.
Can anybody help?
Thanks
Aeon512
I wouldn't know if boost::program_options allows the use-case you are trying, but the error you are getting is because your are trying to pass an object as a template type to po::value<>. If the size is known at compile-time, you could have the size be passed in as a template parameter.
template< typename T, size_t size >
class MyClass {
T m_data[size];
public:
// ...
};
And then use it like so:
po::value< MyClass<int, 2> >()
You should also look into using Boost.Array instead that I guess fulfills what you are trying to implement.
I would write it like this:
MyClass<int> mine(2);
generic.add_options() ("myclass", po::value(&mine), "Read MyClass");
Then all that needs to be done is to define an input stream operator like this:
std::istream& operator >>(std::istream& source, MyClass& target);
Then Boost Program Options will invoke this stream operator when the myclass option is used, and your object will be automatically populated according to that operator's implementation, rather than having to later call one of the Program Options functions to extract the value.
If you don't prefer the above syntax, something like should work too:
generic.add_options() ("myclass", po::value<MyClass<int> >()->default_value(MyClass<int>(2)), "Read MyClass");
This way you would be creating the instance of your class directly with your desired constructor argument outside of the template part where runtime behavior isn't allowed. I do not prefer this way because it's verbose and you end up needing to call more functions later to convert the value.

difference between static T const and static const T

Assuming that T is an arbitrary type and we're talking about Objective-C. Then what is the difference between
static T const x = ....
and
static const T x = ....
?
They are the same.
A little background about const:
Objective-C, just like C, uses the Clockwise/Spiral Rule. In a case where you have only modifiers at the left side of the variable (of foo) you read stuff going from right to left:
int * const * var;
is read: var is a pointer to a constant pointer to integer.
However const has the same effect when it's before or after the first type:
int const var; // constant integer
const int var; // constant integer, same as above
static, instead, affects the whole variable: it's the variable to be static, not the element pointed by it or anything else: a pointer to integer can be used both to point to a static integer, or to an automatic integer without distinction, and C doesn't provide a syntax to declare a pointer able to point to static variables (or to automatic variables) only.
static int * x; // x is a static pointer to integer
int static * y; // as above y is a static pointer to integer
int * static z; // THIS SYNTAX IS NOT ALLOWED
// but if it was, it would mean the same thing
For this reason I prefer to place it before any const modifier, but it doesn't actually matter.
static const int * const * x; // this is what I do
I believe the distinction is only important for pointer types; for example 'char *'.
const char *p means that the buffer pointed to by p cannot be updated but pointer p itself can be changed (typically incremented with p++), for example:
void f(const char *p)
{
while (*p != '\0')
{
putc(*p);
p++;
}
}
char * const p means that the buffer pointed to by p can be updated but pointer p cannot be changed.
EDIT Thanks for JeremyP for the following comment:
It's quite common in Apple's APIs to define string constants (instead of using #defines), especially if the string is an NSString i.e. NSString * const kFoo = #"bar";

Doxygen for C++ template class member specialization

When I write class templates, and need to fully-specialize members of those classes, Doxygen doesn't recognize the specialization - it documents only the generic definition, or (if there are only specializations) the last definition. Here's a simple example:
===MyClass.hpp===
#ifndef MYCLASS_HPP
#define MYCLASS_HPP
template<class T> class MyClass{
public:
static void foo();
static const int INT_CONST;
static const T TTYPE_CONST;
};
/* generic definitions */
template<class T>
void MyClass<T>::foo(){
printf("Generic foo\n");
}
template<class T>
const int MyClass<T>::INT_CONST = 5;
/* specialization declarations */
template<> void MyClass<double>::foo();
template<> const int MyClass<double>::INT_CONST;
template<> const double MyClass<double>::TTYPE_CONST;
template<> const char MyClass<char>::TTYPE_CONST;
#endif
=== MyClass.cpp ===
#include "MyClass.hpp"
/* specialization definitions */
template<>
void MyClass<double>::foo(){
printf("Specialized double foo\n");
}
template<> const int MyClass<double>::INT_CONST = 10;
template<> const double MyClass<double>::TTYPE_CONST = 3.141;
template<> const char MyClass<char>::TTYPE_CONST = 'a';
So in this case, foo() will be documented as printing "Generic foo," INT_CONST will be documented as set to 5, with no mention of the specializations, and TTYPE_CONST will be documented as set to 'a', with no mention of 3.141 and no indication that 'a' is a specialized case.
I need to be able to document the specializations - either within the documentation for MyClass<T>, or on new pages for MyClass<double>, MyClass<char>. How do I do this? Can Doxygen even handle this? Am I possibly doing something wrong in the declarations/code structure that's keeping Doxygen from understanding what I want?
I should note two related cases:
A) For templated functions, specialization works fine, e.g.:
/* functions that are global/in a namespace */
template<class T> void foo(){ printf("Generic foo\n"); }
template<> void foo<double>(){ printf("Specialized double foo\n"); }
This will document both foo<T>() and foo<double>().
B) If I redeclare the entire template, i.e. template<> class MyClass<double>{...};, then MyClass<double> will get its own documentation page, as a seperate class. But this means actually declaring an entirely new class - there is no relation between MyClass<T> and MyClass<double> if MyClass<double> itself is declared. So I'd have to redeclare the class and all its members, and repeat all the definitions of class members, specialized for MyClass<double>, all to make it appear as though they're using the same template. Very awkward, feels like a kludge solution.
Suggestions? Thanks much :)
--Ziv
Further seeking indicates that this issue was an open bug, fixed in Doxygen 1.8.10.
This bug appears to be fixed 3 weeks ago