Add bit_width functions

Add the following functions in `src/util.hpp`:

    template<typename T> inline std::size_t bit_width();
    template<typename T> inline std::size_t bit_width(T x);

These functions compute the size, in bits, of a type or value, providing
a convenient and self-documenting name for the underlying expression,
`sizeof(…) * std::numeric_limits<unsigned char>::digits`.

This commit adds two additional header `#include` directives in
`src/util.hpp`. The newly included headers are as follows:

  - `<cstddef>`, for `std::size_t`; and
  - `<limits>`, for `std::numeric_limits`.

At first, I obtained the bit width of a byte using the C preprocessor
macro `CHAR_BIT`, defined in the C standard library header `<climits>`,
rather than using `std::numeric_limits<unsigned char>::digits`, but I
subsequently switched to using `std::numeric_limits` per Soliton’s
recommendation at 2014-03-17 21:36Z in the `#wesnoth-dev` IRC channel on
the freenode IRC network (<irc://chat.freenode.net/%23wesnoth-dev>).
This commit is contained in:
8573 2014-03-17 18:19:19 +00:00
parent e5ea7824d1
commit 1c28c514a9
2 changed files with 50 additions and 0 deletions

View File

@ -18,6 +18,8 @@
#include "util.hpp"
#include <boost/cstdint.hpp>
BOOST_AUTO_TEST_SUITE( util )
BOOST_AUTO_TEST_CASE( test_lexical_cast )
@ -74,6 +76,19 @@ BOOST_AUTO_TEST_CASE( test_lexical_cast_default )
BOOST_CHECK( result6 >= 0.499 && result6 <= 0.511 );
}
BOOST_AUTO_TEST_CASE( test_bit_width )
{
BOOST_CHECK( bit_width<boost::uint8_t>() == 8 );
BOOST_CHECK( bit_width<boost::uint16_t>() == 16 );
BOOST_CHECK( bit_width<boost::uint32_t>() == 32 );
BOOST_CHECK( bit_width<boost::uint64_t>() == 64 );
BOOST_CHECK( bit_width((boost::uint8_t) 0) == 8 );
BOOST_CHECK( bit_width((boost::uint16_t) 0) == 16 );
BOOST_CHECK( bit_width((boost::uint32_t) 0) == 32 );
BOOST_CHECK( bit_width((boost::uint64_t) 0) == 64 );
}
/* vim: set ts=4 sw=4: */
BOOST_AUTO_TEST_SUITE_END()

View File

@ -22,6 +22,8 @@
#include "global.hpp"
#include <cmath>
#include <cstddef>
#include <limits>
#include <math.h> // cmath may not provide round()
#include <vector>
#include <sstream>
@ -202,6 +204,39 @@ bool in_ranges(const Cmp c, const std::vector<std::pair<Cmp, Cmp> >&ranges) {
inline bool chars_equal_insensitive(char a, char b) { return tolower(a) == tolower(b); }
inline bool chars_less_insensitive(char a, char b) { return tolower(a) < tolower(b); }
/**
* Returns the size, in bits, of an instance of type `T`, providing a
* convenient and self-documenting name for the underlying expression:
*
* sizeof(T) * std::numeric_limits<unsigned char>::digits
*
* @tparam T The return value is the size, in bits, of an instance of this
* type.
*
* @returns the size, in bits, of an instance of type `T`.
*/
template<typename T>
inline std::size_t bit_width() {
return sizeof(T) * std::numeric_limits<unsigned char>::digits;
}
/**
* Returns the size, in bits, of `x`, providing a convenient and
* self-documenting name for the underlying expression:
*
* sizeof(x) * std::numeric_limits<unsigned char>::digits
*
* @tparam T The type of `x`.
*
* @param x The return value is the size, in bits, of this object.
*
* @returns the size, in bits, of an instance of type `T`.
*/
template<typename T>
inline std::size_t bit_width(T x) {
return sizeof(x) * std::numeric_limits<unsigned char>::digits;
}
#ifdef __GNUC__
#define LIKELY(a) __builtin_expect((a),1) // Tells GCC to optimize code so that if is likely to happen
#define UNLIKELY(a) __builtin_expect((a),0) // Tells GCC to optimize code so that if is unlikely to happen