Doxygen: strip top level namespace - c++

When working with library ABC, it natural that all names are included into the same top level namespace. Is it possible to remove top level namespace from class names, but show inclosed namespaces?

There is no such option inside of Doxygen. Still you can use preprocessor to make it work.
#ifndef DOXY_PARSER
#define LIB_NAMESPACE_STARTS namespace lib_namespace { /##/
#define LIB_NAMESPACE_ENDS } /##/
#define LIB_NAMESPACE lib_namespace
#else
#define LIB_NAMESPACE_STARTS /##/
#define LIB_NAMESPACE_ENDS /##/
#define LIB_NAMESPACE
#endif
You should include this code into some common header and set predefined DOXY_PARSER macro in Doxygen options. This workaround makes using of library namespace less convenient but it is not so crucial.
LIB_NAMESPACE_STARTS();
namespace internal_namespace {
struct Trololo {};
}
LIB_NAMESPACE::internal_namespace::Trololo T;
LIB_NAMESPACE_ENDS();

There is a general problem with the previous solution, it is not valid when using Qt. The moc'ing process doesn't use the preprocessor and the namespace is not used (leading to a compile time error).
One possible solution would be to use a #define QT_NAMESPACE lib_namespace but it will move the whole Qt to that namespace.
The next solution is more general (I've kept the macros name for convenience):
#ifndef DOXY_PARSER
#define LIB_NAMESPACE lib_namespace
#define LIB_NAMESPACE_STARTS namespace LIB_NAMESPACE { /##/
#if (defined MOCED_FILE)
#define LIB_NAMESPACE_ENDS } using namespace LIB_NAMESPACE; /##/
#else
#define LIB_NAMESPACE_ENDS } /##/
#endif
#define USING_LIB_NAMESPACE using namespace LIB_NAMESPACE; /##/
#else
#define LIB_NAMESPACE_STARTS /##/
#define LIB_NAMESPACE_ENDS /##/
#define LIB_NAMESPACE
#define USING_LIB_NAMESPACE /##/
#endif
Where MOCED_FILE is a define exclusive for mocs. If you are using CMake, you can specify such option using:
QT4_WRAP_CPP(mocSources qt_file1.h qt_file2.h)
SET_SOURCE_FILES_PROPERTIES(${mocSources} PROPERTIES COMPILE_FLAGS "-DMOCED_FILE")

Related

How to use preprocessor directives to include file twice with different code?

I am trying to make a C++/CLI wrapper for my native C++ project so that I can use it in C#. So far I've wrapped the classes and functions that I need, but I've been trying to find a way to do the same for Enums without having to copy and paste the code to the wrapper.
I've tried looking up ways to wrap enums, but it seems that there's no way to use the enums that are from the native C++ code without having to cast/rewrite the code in the wrapper layer. So I found a solution where you use preprocessor directives and include the enums twice into the wrapper, but it seems not to be working for some reason.
Native Code (Enums.h)
#pragma once
#if defined MANAGED && !defined ENUMS_MANAGED_H
#define ENUMS_MANAGED_H
#define NAMESPACE managed
#define ENUM public enum class
#elif !defined MANAGED && !defined ENUMS_NATIVE_H
#define ENUMS_NATIVE_H
#define NAMESPACE native
#define ENUM enum class
#endif
namespace NAMESPACE
{
ENUM numbers
{
ONE = 1,
TWO = 2,
}
}
Managed Code (Wrapper.h)
#pragma once
#ifndef WRAPPER_H
#define WRAPPER_H
#include "Native.h" //Other native code which also includes Enums.h
#define MANAGED
#include "Enums.h"
namespace managed
{
managed::numbers num = managed::numbers::ONE; //managed does not contain 'numbers'
}
#endif //!WRAPPER_H
C# Code (Main.cs)
using managed; //managed project added as reference
static void main(String[] args)
{
Console.WriteLine((int) numbers.ONE); //managed does not contain 'numbers'
}
I expect to be able to use managed::numbers in the managed project alongside native::numbers. I also expect to be able to use the numbers enum in C#. However, visual studio has not been able to do this. I've tried rearranging the includes as well but that doesn't seem to work.
I made a test file in the managed class that includes Enums.h, but not Native.h:
TestFile.h
#ifndef TESTFILE_H
#define TESTFILE_H
#define MANAGED
#include "Enums.h"
namespace managed
{
managed::numbers num = managed::numbers::ONE; //Works
}
#endif //!TESTFILE_H
This works, but I also need to be able to include Native.h and use the enums from there as well
Edit:
Using #robthebloke answer,
What I got to work is in Enums.h to do:
#pragma once
// to disable error in EnumsImpl.h
#define BUILDING_ENUMS
#include "EnumsImpl.h"
#undef BUILDING_ENUMS
And then in Wrapper.h:
#pragma once
#ifndef WRAPPER_H
#define WRAPPER_H
#include "Native.h"
#define BUILDING_ENUMS
#define MANAGED
#include "EnumsImpl.h"
#undef MANAGED
#undef BUILDING_ENUMS
#endif
Is there any way to just use one file instead of having to use EnumsImpl.h?
EnumsImpl.h
// guard against incorrect usage.
#if !defined(BUILDING_ENUMS)
#error "Do not include this file directly, include Enums.h instead"
#endif
// choose macros for below
#if defined MANAGED
#define NAMESPACE managed
#define ENUM public enum class
#elif !defined MANAGED
#define NAMESPACE native
#define ENUM enum class
#endif
namespace NAMESPACE
{
ENUM numbers
{
ONE = 1,
TWO = 2,
}
}
#undef NAMESPACE
#undef ENUM
Enums.h
#pragma once
// to disable error in EnumsImpl.h
#define BUILDING_ENUMS
// unmanaged
#include "EnumsImpl.h"
// managed
#define MANAGED
#include "EnumsImpl.h"
// remove temp defines
#undef MANAGED
#undef BUILDING_ENUMS
An Alternative...
#define DefEnum(NAMESPACE, ENUM) \
namespace NAMESPACE \
{ \
ENUM numbers \
{ \
ONE = 1, \
TWO = 2, \
}; \
}
DefEnum(dave, enum class);

How to fight external include that always re-define it's stuff

For example assert.h:
...
#ifdef NDEBUG
#define assert(_Expression) ((void)0)
#else /* NDEBUG */
...
This area isn't surrendered by #ifdef, #define, #endif or having #pragma once.
I want to define my own assert function, so I #undef it and creates it, but then when a file includes anything after that includes assert.h it overrides my assert function I made before that include...
For example:
#include "my_assert.hpp"
#include <iostream.h>
My my_assert will lose effect and use assert.h's define.

Make own macros precede libraries macros in c++

I have something like this in header.h:
#ifdef SOME_MACRO
#define MACRO_A
//Some code 1
#else
#define MACRO_A
//Some code 2
#endif
In main.cpp:
#include "header.h"
#define SOME_MACRO
...
MACRO_A; //It should be Some code 1
Is there a way to make SOME_MACRO definition in main.cpp affect header.h?
Putting #define SOME_MACRO before the header doesn't make changes.
First, yes you have to put the definition of your selector before the include statement:
#define SOME_MACRO // <<<<<<<<<<<<<<<<<<<<<<<
#include "header.h"
Second, if I take your sample literally, you probably missed that all code in a macro definition needs to go in a single line:
#ifdef SOME_MACRO
// Note the escaped line endings below: \
#define MACRO_A \
//Some code 1
#else
#define MACRO_A \
//Some code 2
#endif

Conditional preprocessing puzzle

I have a problem where I can't seem to get conditional #define preprocessors to work correctly. For example:
#define WIN32_BUILD
#ifdef WIN32_BUILD
#define PCH "stdafx.h"
#else
#define PCH "xyz.h"
#endif
#include PCH
If I use this form, the compiler tells me that it can't find 'stdafx.h'. OK, that seems odd, so if I change the code to....
#define WIN32_BUILD
#ifdef WIN32_BUILD
#define PCH "xyz.h"
#else
#define PCH "stdafx.h"
#endif
#include PCH
Then the file defined in PCH gets picked up and everything compiles fine. This seems odd to me, almost like the preprocessor is ignoring the #if directives and just using all the #defines that it encounters.
Obviously I am doing something wrong, and I was hoping that someone could help me understand this.
When a project has the precompiled header feature turned on the preprocessor ignores everything that comes before #include "stdafx.h"
So your #define statements are ignored.
TL:DR; #define defines the symbol, #ifdef tests if the symbol is defined not whether it has a value.
#define WIN32_BUILD
This defines a pre-processor token, WIN32_BUILD. The token has no value. Anywhere you use the token 'WIN32_BUILD' the pre-processor will substitute the empty string, i.e. nothing.
#ifdef WIN32_BUILD
This checks if the pre-processor token WIN32_BUILD is defined. It is, you just defined it.
#ifdef WIN32_BUILD
// true - this code is included.
#define PCH "stdafx.h"
This defines the pre-processor token, PCH, and assigns it the value "stdafx.h"
#else
#define PCH "xyz.h"
#endif
This code is ignored, because WIN32_BUILD was defined.
It looks as though you were expecting 'ifdef' to only evaluate to true if the expression was not defined /to/ something.
#define a
#define b SOMETHING
#ifdef a
// you are expecting this to be ignored
#endif
#ifdef b
// and expecting this not to be ignored
#endif
#ifdef and #if defined(...) do the same thing.
#define a
#define b SOMETHING
#if defined(a) && defined(b)
// this code will be evaluated, both tokens are defined.
#endif
This feature of pre-processor tokens is often used to support conditional functionality:
#if HAVE_CPP11_OVERRIDE_KEYWORD
#define OVERRIDE_FN override
#else
#define OVERRIDE_FN
#endif
struct A {
virtual void foo() {}
};
struct B : public A {
void foo() OVERRIDE_FN {}
};
In the above code, the override keyword is only added if the system supports it (determined outside of the code).
So a compiler with override sees
struct B : public A {
void foo() override {}
};
a compiler without it sees
struct B : public A {
void foo() {}
};
Note: The opposite of "ifdef" is "ifndef":
#define a
#define b SOMETHING
#undef c
//#define d // << we didn't define it.
int main() {
#ifdef a
#pramga message("a is defined")
#else
#pramga message("a is UNdefined")
#endif
#ifdef b
#pragma message("b is defined")
#else
#pramga message("b is UNdefined")
#endif
#ifdef c
#pramga message("c is defined")
#endif
#else
#pramga message("c is UNdefined")
#endif
#ifdef d
#pramga message("d is defined")
#endif
#else
#pramga message("d is UNdefined")
#endif
#ifndef d
#pragma message("d is not defined")
#endif
#ifndef a
#pragma message("a is not defined")
#endif
return 0;
}
You can assign a pre-processor token numeric values and test them with #if
#if _MSC_VER
#define WIN32_BUILD 1
#else
#define WIN32_BUILD 0
#endif
#if WIN32_BUILD
#include <Windows.h>
#endif
But, especially when doing cross-platform programming, people tend to use ifdef variants rather than numeric checks, because the value checks require you to explicitly ensure all of the tokens are defined with a value. It's a lot easier just to only define them when you need them.

Confusing nesting of numerous #ifndef statements (with no values) in C++

Maybe I'm missing something, but could some please explain the "logic" behind the following code?
#ifndef _PTRDIFF_T
#ifndef _T_PTRDIFF_
#ifndef _T_PTRDIFF
#ifndef __PTRDIFF_T
#ifndef _PTRDIFF_T_
#ifndef _BSD_PTRDIFF_T_
#ifndef ___int_ptrdiff_t_h
#ifndef _GCC_PTRDIFF_T
#define _PTRDIFF_T
#define _T_PTRDIFF_
#define _T_PTRDIFF
#define __PTRDIFF_T
#define _PTRDIFF_T_
#define _BSD_PTRDIFF_T_
#define ___int_ptrdiff_t_h
#define _GCC_PTRDIFF_T
#ifndef __PTRDIFF_TYPE__
#define __PTRDIFF_TYPE__ long int
#endif
typedef __PTRDIFF_TYPE__ ptrdiff_t;
#endif /* _GCC_PTRDIFF_T */
#endif /* ___int_ptrdiff_t_h */
#endif /* _BSD_PTRDIFF_T_ */
#endif /* _PTRDIFF_T_ */
#endif /* __PTRDIFF_T */
#endif /* _T_PTRDIFF */
#endif /* _T_PTRDIFF_ */
#endif /* _PTRDIFF_T */
Why is this preferred over a simple:
#ifndef xyz
#define xyz
#endif
???
I can see they are nested, but it is very confusing. ...and btw, just what are they defining, as there are no values after the identifiers???
The logic is to only define the macros if none of them is defiend. However, I would certainly refactor it into:
#if !defined(_PTRDIFF_T) && !defined(_T_PTRDIFF_) && //... well, you get the idea
#define _PTRDIFF_T
#define _T_PTRDIFF_
//...
#ifndef __PTRDIFF_TYPE__
#define __PTRDIFF_TYPE__ long int
#endif
typedef __PTRDIFF_TYPE__ ptrdiff_t;
#endif
As to the second question: you can define a macro without a replacement text (it would just expand to nothing if used). Such macros are often used for conditional inclusion of code based on #ifdef or #ifndef.
They're checking that all these identifiers have been defined which would be in other already included headers. If they're all defined then we define a few new identifiers.
You don't need to give a value to the identifier, for example you wouldn't give a value to your #include guards.