Browse Source

Removed SizeTraits, SizeBasedCall and related mess.

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
Vladimír Vondruš 14 years ago
parent
commit
c8ef795cce
  1. 2
      src/CMakeLists.txt
  2. 25
      src/SizeTraits.cpp
  3. 206
      src/SizeTraits.h

2
src/CMakeLists.txt

@ -27,7 +27,6 @@ set(Magnum_SRCS
Renderbuffer.cpp
Resource.cpp
Shader.cpp
SizeTraits.cpp
Timeline.cpp
TypeTraits.cpp
@ -77,7 +76,6 @@ set(Magnum_HEADERS
Resource.h
ResourceManager.h
Shader.h
SizeTraits.h
Swizzle.h
Texture.h
Timeline.h

25
src/SizeTraits.cpp

@ -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
}

206
src/SizeTraits.h

@ -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…
Cancel
Save