Skip to content

Commit

Permalink
Add bit_width functions
Browse files Browse the repository at this point in the history
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>).
  • Loading branch information
8573 committed Mar 20, 2014
1 parent e5ea782 commit 1c28c51
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 0 deletions.
15 changes: 15 additions & 0 deletions src/tests/test_util.cpp
Expand Up @@ -18,6 +18,8 @@

#include "util.hpp"

#include <boost/cstdint.hpp>

BOOST_AUTO_TEST_SUITE( util )

BOOST_AUTO_TEST_CASE( test_lexical_cast )
Expand Down Expand Up @@ -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()
35 changes: 35 additions & 0 deletions src/util.hpp
Expand Up @@ -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>
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 1c28c51

Please sign in to comment.