In a very large code base I want to automatically add classes and functions to groups based on the project they are defined in. Luckily, I already have a compiler macro PROJECT_NAME_EXPORTED appended to each exported function and class:
enum PROJECT_NAME_EXPORTED MyEnum ....
class PROJECT_NAME_EXPORTED MyClass ....
PROJECT_NAME_EXPORTED void myFunction(int a) ....
The macro follows the same convention but is different for every subproject, e.g. SOME_PROJECT_EXPORTED, OTHER_EXPORTED.
So having a list of all projects I do the following in my doxygen's CMake:
foreach(name ${LIST_OF_PROJECTS})
SET(DOXYGEN_PREDEFINED_MACROS "${DOXYGEN_PREDEFINED_MACROS}\"${name}_EXPORTED=(void)/** #ingroup ${name}*/\" \\ \n")
endforeach()
And this almost works, the classes are listed correctly but the functions are listed with two return types (the actual one and the (void) I injected above):
void void myFunction(int a)
The culprit is obviously said injected (void) but if I leave it out, the classes are not correctly added to the group anymore.
Is there a different "dummy" word to add here or an entirely different solution for automatically adding all entities in a project to the corresponding doxygen group?
Related
I just one to make sure no one will derive from my non-polymorphic class, so I used following syntax:
class Foo final
{
Foo();
~Foo(); // not virtual
void bar();
};
In The C++ programming language I read that final can be used together with override for classes containing virtual member functions. I tried my code sample in VS 2013 and it compiles without any warning.
Is it allowed to use keyword final for non-polymorphic classes to prevent derivation from the class ? Does the keyword override make sense with non-polymorphic classes ?
The C++ grammar allows final to appear in two different places. One is a class-virt-specifier which can appear after the class name in a class declaration, which is how you've used it. Despite the name, using a class-virt-specifer has nothing to do with virtual functions and is allowed in non-polymorphic classes.
The other place it can be used is a virt-specifier on a member function. If present, a virt-specifer sequence consists of one or both of final and override, but is only allowed on virtual functions (9.2 [class.mem] "A virt-specifier-seq shall contain at most one of each virt-specifier. A virt-specifier-seq shall appear only in the declaration of a virtual member function (10.3)."). So override can only be used on virtual functions, so cannot be used in non-polymorphic types.
yes it is allowed even if your class is not virtual:
from cppreference:
http://en.cppreference.com/w/cpp/language/final
When used in a class definition, final specifies that this class may
not appear in the base-specifier-list of another class definition (in
other words, cannot be derived from).
The override keyword on the other hand makes no sense for non polymorphic classes.
I tried to split some polymorphic classes to be serialized into a dll file. Then I get an exception for unregistered polymorphic type. The problem seems to be that the code create two instances of the map used to lookup polymorphic objects (Kept by template class cereal::detail::StaticObject). If I put the CEREAL_REGISTER_TYPE into the project that do the serialization, then everything works nice.
So I wonder if anyone know if it is possible to do some tricks to be able to do the registration in the dll file?
Is it possible to force the program to use the same instance of the cereal::detail::StaticObject class?
As of cereal v1.1.0 this problem can be solved by moving the polymorphic type registration to a header file, which will ensure that any translation unit including that header properly initializes its StaticObject. Just remember to include the archives you wish to bind to prior to calling the registration macro.
There's more information available on the [main cereal documentation] site(http://uscilab.github.io/cereal/polymorphism.html), which has also been updated for 1.1.
I managed to solve this problem with 1.3.0 (should work with 1.1 too) by having the following statements in an hpp in a DLL at the bottom of my DLL dependency chain. Let's call it core.dll. In that DLL I will have a file called config.hpp with the following traditional macro. CMake will define core_EXPORTS when generating the build scripts for core.dll
#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__)
# if defined(core_EXPORTS)
# define CORE_DECL __declspec(dllexport)
# else
# define CORE_DECL __declspec(dllimport)
# endif
#endif
Then in another export.hpp in core.dll I have the following
namespace cereal {
namespace detail {
// these declspecs will ensure that the polymorphic loader/saver registrations will
// all happen against the binding maps in core.dll
template class CORE_DECL StaticObject<InputBindingMap<PortableBinaryInputArchive>>;
template class CORE_DECL StaticObject<InputBindingMap<JSONInputArchive>>;
template class CORE_DECL StaticObject<OutputBindingMap<PortableBinaryOutputArchive>>;
template class CORE_DECL StaticObject<OutputBindingMap<JSONOutputArchive>>;
// add similar statements for other archive types as needed
template class CORE_DECL StaticObject<Versions>;
} // namespace detail
} // namespace cereal
All other cpp files in the other dll projects will #include core/export.hpp thereby telling the linker to use the cereal StaticObjects in core.dll. If you debug the InputBindingCreator contructor you will notice that every class is now being registered in the same binding map.
I think it would be useful to add the above to the cereal documentation on this topic.
I'll start by saying that I'm working off the assumption that static array initializers are turned into private nested classes by the compiler, usually with names like __StaticArrayInitTypeSize=12. As I understand it, having read this extremely informative article, these private classes are value types, and they aren't tagged with the CompilerGeneratedAttribute class.
I'm working on a project that needs to process certain types and ignore others.
I have to be able to process custom struct types, which, like the generated static array initializer classes, are value types. I must ignore the generated static array initializer classes. I also must ignore enumerations and delegates.
I'm pulling these classes with Linq, like so:
var typesToProcess = allTypes.Where(type => !type.IsEnum &&
!type.IsArray &&
!type.IsSubclassOf(typeof(Delegate)));
I'm fairly sure that the IsArray property isn't what I think it is. At any rate, the generated static array initializer class still shows up in the typesToProcess Enumerable.
Has anyone else dealt with this? How can I discern the difference between a custom struct and a generated static array initializer class? I could hack it by doing a string comparison of the type name against __StaticArrayInitTypeSize, but is there a cleaner solution?
Well, having just tried it myself with the C# 4 compiler, I got an internal class called <PrivateImplementationDetails>{D1E23401-19BC-4B4E-8CC5-2C6DDEE7B97C} containing a private nested struct called __StaticArrayInitTypeSize=12.
The class contained an internal static field of the struct type called $$method0x6000001-1. The field itself was decorated with CompilerGeneratedAttribute.
The problem is that all of this is implementation-specific. It could change in future releases, or it could be different from earlier releases too.
Any member name containing <, > or = is an "unspeakable" name which will have been generated by the compiler, so you can view that as a sort of implicit CompilerGenerated, if that's any use. (There are any number of other uses for such generated types though.)
Every so often, I'm done modifying a piece of code and I would like to "lock" or make a region of code "read only". That way, the only way I can modify the code is if I unlock it first. Is there any way to do this?
The easiest way which would work in many cases is to make it a partial type - i.e. a single class whose source code is spread across multiple files. You could then make one file read-only and the other writable.
To declare a partial type, you just use the partial contextual keyword in the declaration:
// MyClass.First.cs:
public partial class MyClass
{
void Foo()
{
Bar();
}
void Baz()
{
}
}
// MyClass.Second.cs:
public partial class MyClass
{
void Bar()
{
Baz();
}
}
As you can see, it ends up as if the source was all in the same file - you can call methods declared in one file from the other with no problems.
Compile it into into a library dll and make it available for reference in other projects.
Split up the code into separate files and then check into a source control system?
Given your rebuttal to partial classes... there is no way that I know of in a single file, short of documentation. Other options?
inheritance; but the protected code in the base-class (in an assembly you control); inheritors can only call the public/protected members
postsharp - stick the protected logic in attributes declared externally
However, both of these still require multiple files (and probably multiple assemblies).
I thought about this, but I would prefer to keep the class in one file. – danmine
Sorry, mac. A bit of voodoo as a SVN pre-commit might catch it but otherwise no solution other than // if you change this code you are fired
This is totally unnecessary if you're using a version control system. Because once you've checked it in, it doesn't matter what part of the code you edit, you can always diff or roll back. Heck, you could accidentally wipe out all the source code and still get it back.
I'm getting a really bad "code smell" from the fact that you want to lock certain parts of the code. I'm guessing that maybe you're doing too much in one class, in which case, refactor it to a proper set of classes. The fact that, after the 10+ years visual studio has existed, this feature isn't available, should suggest that perhaps your desire to do this is a result of poor design.
I have found that there is generally a singe type or namespace that takes in any particular enum as a parameter and as a result I have always defined those enums there. Recently though, I had a co-worker make a big deal about how that was a stupid thing to do, and you should always have an enum namespace at the root of your project where you define everyone of your enum types.
Where is the best place to locate enum types?
Why treat enums differently to other types? Keep them in the same namespace as they're likely to be used - and assuming they're going to be used by other classes, make them top-level types in their own files.
The only type of type which I do commonly clump together is delegates - I sometimes have a Delegates.cs file with a bunch of delegates in. Less so with .NET 3.5 and Func/Action, mind you.
Also, namespaces are for separation of things that belong together logically. Not all classes belong in the same namespace just because they are classes. Likewise, not all enums belong in the same namespace just because they are enums. Put them with the code they logically belong in.
I generally try to put all my different types (classes, interfaces and enums) in their own files, regardless of how small they are. It just makes it much easier to find and manage the file they're in, especially if you don't happen to be in Visual Studio and have the "go to definition" feature available. I've found that nearly every time I've put a "simple" type like that in another class, I end up either adding on to it later on, or reusing it in a way that it no longer makes sense for it to not have its own file.
As far as which namespace, it really depends on the design of whatever you're developing. In general, I try to mimic the .NET framework's convention.
I try to put everything associated with a class in the class. That includes not just enums, but also constants. I don't want to go searching elsewhere for the file or class containing the enums. In a large app with lots of classes and folders, it wouldn't always be obvious where to put the enum file so it would be easy to find.
If the enum if used in several closely-related classes, you could create a base class so that the common types like enums are shared there.
Of course, if an enum is really generic and widely used, you may want to create a separate class for them, along with other generic utilities.
I think you put Enums and Constants in the class that consumes them or that uses them to control code decisions the most and you use code completion to find them. That way you don't have to remember where they are, they are associated with the class. So for example if I have a ColoredBox class then I don't have to think about where they are at. They would be part of ColoredBox. ColoredBox.Colors.Red, ColoredBox.Colors.Blue etc. I
I think of the enum and constant as a property or description of that class.
If it used by multiple classes and no one class reigns supreme then it is appropriate to have an enum class or constants class.
This follows rules of encapsulation. Isolating properties from dissimilar classes. What if you decide to change the RGB of Red in Cirle objects but
you don't want to change the red for ColoredBox objects? Encapsulating their properties enables this.
I use nested namespaces for this. I like them better than putting the enum within a class because outside of the class you have to use the full MyClass::MyEnum usage even if MyEnum is not going to clash with anything else in scope.
By using a nested namespace you can use the "using" syntax. Also I will put enums that relate to a given subsystem in their own file so you don't get dependency problems of having to include the world to use them.
So in the enum header file you get:
// MyEnumHeader.h
// Consolidated enum header file for this dll,lib,subsystem whatever.
namespace MyApp
{
namespace MyEnums
{
enum SomeEnum { EnumVal0, EnumVal1, EnumVal2 };
};
};
And then in the class header file you get:
// MyInterfaceHeader.h
// Class interfaces for the subsystem with all the expected dependencies.
#include "MyEnumHeader.h"
namespace MyApp
{
class MyInterface
{
public:
virtual void DoSomethingWithEnumParam (MyEnums::SomeEnum enumParam) = 0;
};
};
Or use as many enum header files as makes sense. I like to keep them separate from the class headers so the enums can be params elsewhere in the system without needing the class headers. Then if you want to use them elsewhere you don't have to have the encapsulating class defs as you would if the enums were declared within the classes.
And as mentioned before, in the outer code you can use the following:
using namespace MyApp::MyEnums;
What environment?
In .NET I usually create an empty class file, rename it to MyEnum or whatever to indicate it holds my enum and just declare it in there.
If my enumeration has any chance of ever being used outside the class I intend to use it, I create a separate source file for the enum. Otherwise I will place it inside the class I intend to use it.
Usually I find that the enum is centered around a single class -- as a MyClassOptions type of thing.
In that case, I place the enum in the same file as MyClass, but inside the namespace but outside the class.
namespace mynamespace
{
public partial class MyClass
{
}
enum MyClassOptions
{
}
}
I tend to define them, where their use is evident in the evident. If I have a typedef for a struct that makes use of it for some reason...
typedef enum {
HI,
GOODBYE
} msg_type;
typdef struct {
msg_type type;
union {
int hivar;
float goodbyevar;
}
} msg;