namespace Magnum { /** @page compilation-speedup Speeding up compilation @brief Techniques for reducing compilation times. @section compilation-forward-declarations Forward declarations instead of includes Essential thing when speeding up compilation is reducing number of `#``include` directives in both headers and source files. %Magnum is strictly applying this policy in all header files, so all types which are not directly used in the header have only forward declarations. For example, when including Magnum.h, you get shortcut typedefs for floating-point vectors and matrices like @ref Vector3 and @ref Matrix4, but to actually use any of them, you have to include the respective header, e.g. Math/Vector3.h. @section compilation-speedup-templates Templates Many things in %Magnum are templated to allow handling of various types and sizes of data, for example whole Scene graph can operate either with `float`s or with `double`s. However, having templated classes and function usually means that the compiler compiles the whole templated code again in each compilation unit (i.e. source file). In linking stage of the application or library the duplicates are just thrown out, which is a waste of compilation time. A few techniques are employed in %Magnum to avoid this. @subsection compilation-speedup-hpp Template headers and implementation files When templated code is too large, it is not stored in header file, but in so-called *template implementation file*. Generally, all header files in %Magnum have `*.h` extension and all source files have `*.cpp` extension. Template implementation files have `*.hpp` extension (hinting that they are something between `*.h` and `*.cpp` files). Template implementation file can be included along the header itself and it will just work, but it doesn't positively affect compilation time. If you are using one template specialization on many places, template implementation files give you the ability to explicitly instantiate the template in some source file. Then you can include only the header everywhere else and leave the rest on the linker. Templated classes which have implementation files state in their documentation all common specializations that are already compiled in the libraries. So, unless the templated class is too generic (ResourceManager for example) or you need something special, you don't have to mess with Object implementation files at all. See Color3 or SceneGraph::Object for an example. Sometimes you however need to use your own specialization and that's why template implementation files are included in the library. For example we want to use @ref SceneGraph::Object "Object" from SceneGraph with @ref SceneGraph::MatrixTransformation3D "MatrixTransformation3D" with `GLdouble` as underlying type, because our scene will span the whole universe. We include the implementation file in dedicated source file and explicitly instantiate the template: @code // Object.cpp #include "SceneGraph/Object.hpp" using namespace Magnum::SceneGraph; template class Object>; @endcode All other files using the same object specialization now need to include only SceneGraph/Object.h header and if we compile our `Object.cpp` together with the rest, the Object specialization will be compiled only once. @subsection compilation-speedup-extern-templates Extern templates Keyword `extern template` is new thing in C++11, attempting to solve compilation time problems. However, when used on whole classes, on some compilers it causes conflicting symbol errors, so in %Magnum its used only for specific functions. This is completely transparent to end user, so no special care is needed. Extern template is used for example for @ref debugoperators "debug operators" for common types of matrices and vectors. */ }