mirror of https://github.com/mosra/magnum.git
Browse Source
The implementation was really frightening and it was really used only in MeshTools::compressIndices(). Other classes like SizeTraits, Pow and Log were just waiting to be deleted, nothing of value was lost.pull/7/head
3 changed files with 0 additions and 233 deletions
@ -1,25 +0,0 @@ |
|||||||
/*
|
|
||||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
|
||||||
|
|
||||||
This file is part of Magnum. |
|
||||||
|
|
||||||
Magnum is free software: you can redistribute it and/or modify |
|
||||||
it under the terms of the GNU Lesser General Public License version 3 |
|
||||||
only, as published by the Free Software Foundation. |
|
||||||
|
|
||||||
Magnum is distributed in the hope that it will be useful, |
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||||
GNU Lesser General Public License version 3 for more details. |
|
||||||
*/ |
|
||||||
|
|
||||||
#include "SizeTraits.h" |
|
||||||
|
|
||||||
namespace Magnum { |
|
||||||
|
|
||||||
#ifndef DOXYGEN_GENERATING_OUTPUT |
|
||||||
static_assert(Pow<2, 3>::value == 8, "Implementation error in Pow meta class"); |
|
||||||
static_assert(Log<2, 9>::value == 3, "Implementation error in Log meta class"); |
|
||||||
#endif |
|
||||||
|
|
||||||
} |
|
||||||
@ -1,206 +0,0 @@ |
|||||||
#ifndef Magnum_SizeTraits_h |
|
||||||
#define Magnum_SizeTraits_h |
|
||||||
/*
|
|
||||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
|
||||||
|
|
||||||
This file is part of Magnum. |
|
||||||
|
|
||||||
Magnum is free software: you can redistribute it and/or modify |
|
||||||
it under the terms of the GNU Lesser General Public License version 3 |
|
||||||
only, as published by the Free Software Foundation. |
|
||||||
|
|
||||||
Magnum is distributed in the hope that it will be useful, |
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||||
GNU Lesser General Public License version 3 for more details. |
|
||||||
*/ |
|
||||||
|
|
||||||
/** @file
|
|
||||||
* @brief Class Magnum::SizeTraits, Magnum::SizeBasedCall, Magnum::Pow, Magnum::Log |
|
||||||
*/ |
|
||||||
|
|
||||||
#include <Utility/Debug.h> |
|
||||||
|
|
||||||
#include "Math/Math.h" |
|
||||||
#include "Magnum.h" |
|
||||||
|
|
||||||
namespace Magnum { |
|
||||||
|
|
||||||
/** @todo Remove/internalize things used only in one place (Math::log, Pow, Log)? Simplify SizeTraits? */ |
|
||||||
|
|
||||||
/**
|
|
||||||
@brief Traits class providing suitable types for given data sizes |
|
||||||
@tparam byte Highest byte needed (counting from zero) |
|
||||||
|
|
||||||
If you use indexed data, you would probably (for performance reasons) want to |
|
||||||
use the smallest type which is able to store all indices in given range. This |
|
||||||
class provides type suitable for given **logarithmic** size of data. For |
|
||||||
example, if you want to store 289 elements, they occupy two bytes, so |
|
||||||
`SizeTraits<1>::%SizeType` is `GLushort`. For convenience you can use Log class |
|
||||||
to compute logarithms at compile time, e.g. |
|
||||||
`SizeTraits<Log<256, 289>::%value>::%SizeType`. |
|
||||||
*/ |
|
||||||
#ifdef DOXYGEN_GENERATING_OUTPUT |
|
||||||
template<std::size_t byte> struct SizeTraits { |
|
||||||
/**
|
|
||||||
* @brief (Unsigned) type able to index the data |
|
||||||
* |
|
||||||
* Not implemented for large sizes (@f$ > 2^{32} @f$ elements), because |
|
||||||
* OpenGL doesn't have any type which would be able to store the indices. |
|
||||||
*/ |
|
||||||
typedef T SizeType; |
|
||||||
}; |
|
||||||
#else |
|
||||||
template<std::size_t byte> struct SizeTraits: public SizeTraits<byte - 1> { |
|
||||||
SizeTraits() = delete; |
|
||||||
}; |
|
||||||
#endif |
|
||||||
|
|
||||||
#ifndef DOXYGEN_GENERATING_OUTPUT |
|
||||||
template<> struct SizeTraits<0> { |
|
||||||
SizeTraits() = delete; |
|
||||||
typedef GLubyte SizeType; |
|
||||||
}; |
|
||||||
template<> struct SizeTraits<1> { |
|
||||||
SizeTraits() = delete; |
|
||||||
typedef GLushort SizeType; |
|
||||||
}; |
|
||||||
template<> struct SizeTraits<2> { |
|
||||||
SizeTraits() = delete; |
|
||||||
typedef GLuint SizeType; |
|
||||||
}; |
|
||||||
template<> struct SizeTraits<4> { |
|
||||||
SizeTraits() = delete; |
|
||||||
/* We don't have size type to store 2^32 values */ |
|
||||||
}; |
|
||||||
#endif |
|
||||||
|
|
||||||
/**
|
|
||||||
@brief Functor for calling templated function with type based on size |
|
||||||
@tparam Base Base struct with templated function `run()`. See below for |
|
||||||
example. |
|
||||||
|
|
||||||
If you have templated function which you want to call with type suitable for |
|
||||||
indexing data of some size, you will probably use cascade of IFs, like this: |
|
||||||
@code |
|
||||||
std::size_t dataSize; |
|
||||||
template<class IndexType> Bar foo(Arg1 arg1, Arg2 arg2, ...); |
|
||||||
|
|
||||||
Bar bar; |
|
||||||
if(dataSize < 256) |
|
||||||
bar = foo<GLubyte>(arg1, arg2, ...); |
|
||||||
else if(dataSize < 65536) |
|
||||||
bar = foo<GLushort>(arg1, arg2, ...); |
|
||||||
// ...
|
|
||||||
@endcode |
|
||||||
But this approach leads to repetitive and unmaintainable code, especially if |
|
||||||
there are many arguments needed to pass to each function. The solution is to |
|
||||||
use this class. The only thing you need is to rename your function to `run()` |
|
||||||
and wrap it in a `struct`: |
|
||||||
@code |
|
||||||
struct Foo { |
|
||||||
template<class IndexType> Bar run(Arg1 arg1, Arg2 arg2, ...); |
|
||||||
}; |
|
||||||
@endcode |
|
||||||
Then you can use this class to call the templated function with the right type |
|
||||||
based on data size: |
|
||||||
@code |
|
||||||
bar = SizeBasedCall<Foo>(dataSize)(arg1, arg2, ...); |
|
||||||
@endcode |
|
||||||
*/ |
|
||||||
template<class Base> struct SizeBasedCall: public Base { |
|
||||||
/**
|
|
||||||
* @brief Constructor |
|
||||||
* @param size Data size |
|
||||||
*/ |
|
||||||
explicit SizeBasedCall(std::size_t size): size(size) {} |
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Functor |
|
||||||
* @param arguments Arguments passed to `Base::run()` |
|
||||||
* @return Return value of `Base::run()` |
|
||||||
* |
|
||||||
* Calls `Base::run()` based on data size (given in constructor). If there |
|
||||||
* is no suitable type for indexing given data size, prints message to |
|
||||||
* error output and returns default-constructed value. |
|
||||||
*/ |
|
||||||
template<typename ...Args> auto operator()(Args&&... arguments) -> decltype(Base::template run<GLubyte>(std::forward<Args>(arguments)...)) { |
|
||||||
switch(Math::log(256, size)) { |
|
||||||
case 0: |
|
||||||
return Base::template run<GLubyte>(std::forward<Args>(arguments)...); |
|
||||||
case 1: |
|
||||||
return Base::template run<GLushort>(std::forward<Args>(arguments)...); |
|
||||||
case 2: |
|
||||||
case 3: |
|
||||||
return Base::template run<GLuint>(std::forward<Args>(arguments)...); |
|
||||||
} |
|
||||||
|
|
||||||
Error() << "SizeBasedCall: no type able to index" << size << "elements."; |
|
||||||
return decltype(Base::template run<GLubyte>(std::forward<Args>(arguments)...))(); |
|
||||||
} |
|
||||||
|
|
||||||
private: |
|
||||||
std::size_t size; |
|
||||||
}; |
|
||||||
|
|
||||||
/**
|
|
||||||
@brief Class for computing integral powers at compile time |
|
||||||
@tparam base Base |
|
||||||
@tparam exponent Exponent |
|
||||||
|
|
||||||
Useful mainly for computing template parameter value, e.g. in conjunction with |
|
||||||
SizeTraits class. |
|
||||||
*/ |
|
||||||
template<std::uint32_t base, std::uint32_t exponent> struct Pow { |
|
||||||
Pow() = delete; |
|
||||||
|
|
||||||
/** @brief Value of the power */ |
|
||||||
enum: std::uint32_t { |
|
||||||
#ifndef DOXYGEN_GENERATING_OUTPUT |
|
||||||
value = base*Pow<base, exponent-1>::value |
|
||||||
#else |
|
||||||
value |
|
||||||
#endif |
|
||||||
}; |
|
||||||
}; |
|
||||||
|
|
||||||
#ifndef DOXYGEN_GENERATING_OUTPUT |
|
||||||
template<std::uint32_t base> struct Pow<base, 0> { |
|
||||||
Pow() = delete; |
|
||||||
|
|
||||||
enum: std::uint32_t { value = 1 }; |
|
||||||
}; |
|
||||||
#endif |
|
||||||
|
|
||||||
/**
|
|
||||||
@brief Class for computing integral logarithms at compile time |
|
||||||
@tparam base Base |
|
||||||
@tparam number Number |
|
||||||
|
|
||||||
Useful mainly for computing template parameter value, e.g. in conjunction with |
|
||||||
SizeTraits class. |
|
||||||
*/ |
|
||||||
template<std::uint32_t base, std::uint32_t number> struct Log { |
|
||||||
Log() = delete; |
|
||||||
|
|
||||||
/** @brief Value of the logarithm */ |
|
||||||
enum: std::uint32_t { |
|
||||||
#ifndef DOXYGEN_GENERATING_OUTPUT |
|
||||||
value = 1+Log<base, number/base>::value |
|
||||||
#else |
|
||||||
value |
|
||||||
#endif |
|
||||||
}; |
|
||||||
}; |
|
||||||
|
|
||||||
#ifndef DOXYGEN_GENERATING_OUTPUT |
|
||||||
template<std::uint32_t base> struct Log<base, 0> { |
|
||||||
Log() = delete; |
|
||||||
enum: std::uint32_t { value = 0 }; |
|
||||||
}; |
|
||||||
template<std::uint32_t base> struct Log<base, 1>: public Log<base, 0> {}; |
|
||||||
#endif |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
#endif |
|
||||||
Loading…
Reference in new issue