From e7539b6fbd205b6bd1ba076ea4eb3383b61c19b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Tue, 13 Nov 2012 00:58:36 +0100 Subject: [PATCH] Improved template implementation files documentation. * ResourceManager won't have template implementation file, as it would add too much work on the user. * Color won't have either, as some internal functions are impossible to explicitly instantiate. --- doc/compilation-speedup.dox | 21 +++++++++++---------- src/Color.h | 4 ++++ src/ResourceManager.h | 11 ++++++++--- 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/doc/compilation-speedup.dox b/doc/compilation-speedup.dox index 5fb7d33da..c1a0802f6 100644 --- a/doc/compilation-speedup.dox +++ b/doc/compilation-speedup.dox @@ -38,17 +38,18 @@ 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. +will just work, but it will negatively affect compilation time. If you are +using one template specialization in many places, the compiler performs +compilation of the same template specialization many times. Template +implementation files give you the ability to explicitly instantiate the +template only once in some dedicated source file. Then you can include just +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. +unless the templated class is too generic or you need something special, you +don't have to mess with template implementation files at all. See +SceneGraph::Object or SceneGraph::AbstractCamera 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 @@ -66,8 +67,8 @@ 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. +SceneGraph/Object.h header. Thus the Object specialization will be compiled +only once in our `Object.cpp` file, saving precious compilation time. @subsection compilation-speedup-extern-templates Extern templates diff --git a/src/Color.h b/src/Color.h index c24866b9d..044fc3579 100644 --- a/src/Color.h +++ b/src/Color.h @@ -143,6 +143,8 @@ range @f$ [0.0, 1.0] @f$. @todo Signed normalization to [-1.0, 1.0] like in OpenGL? */ +/* Not using template specialization because some internal functions are + impossible to explicitly instantiate */ template class Color3: public Math::Vector3 { public: /** @brief Corresponding floating-point type for HSV computation */ @@ -287,6 +289,8 @@ MAGNUM_VECTOR_SUBCLASS_OPERATOR_IMPLEMENTATION(Color3, 3) See Color3 for more information. */ +/* Not using template specialization because some internal functions are + impossible to explicitly instantiate */ template class Color4: public Math::Vector4 { public: /** @copydoc Color3::FloatingPointType */ diff --git a/src/ResourceManager.h b/src/ResourceManager.h index d5f9b4e34..a8ad00d9b 100644 --- a/src/ResourceManager.h +++ b/src/ResourceManager.h @@ -133,12 +133,12 @@ namespace Implementation { inline Data(): data(nullptr), state(ResourceDataState::Mutable), policy(ResourcePolicy::Manual), referenceCount(0) {} - Data(Data&& other): data(other.data), state(other.state), policy(other.policy), referenceCount(other.referenceCount) { + inline Data(Data&& other): data(other.data), state(other.state), policy(other.policy), referenceCount(other.referenceCount) { other.data = nullptr; other.referenceCount = 0; } - ~Data() { + inline ~Data() { CORRADE_ASSERT(referenceCount == 0, "ResourceManager: cannot destruct it while data are still referenced", ); delete data; } @@ -389,6 +389,8 @@ template class Resource { Provides storage for arbitrary set of types, accessible globally using instance(). +@section ResourceManager-usage Usage + Each resource is referenced from Resource class. For optimizing performance, each resource can be set as mutable or final. Mutable resources can be modified by the manager and thus each %Resource instance asks the manager for @@ -444,6 +446,9 @@ cube->draw(); - Destroying resource references and deleting manager instance when nothing references the resources anymore. */ +/* Due to too much work involved with explicit template instantiation (all + Resource combinations, all ResourceManagerData...), this class doesn't have + template implementation file. */ template class ResourceManager: protected Implementation::ResourceManagerData... { public: /** @brief Global instance */ @@ -557,7 +562,7 @@ template class ResourceManager: protected Implementation::Resour }; /** @debugoperator{Magnum::ResourceKey} */ -template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const ResourceKey& value) { +template inline Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const ResourceKey& value) { return debug << static_cast&>(value); }