Merge pull request #2492 from janisozaur/countof

countof with type safety
This commit is contained in:
Ted John 2015-12-14 23:46:11 +00:00
commit 6466a33449
7 changed files with 62 additions and 16 deletions

View File

@ -208,6 +208,7 @@
<ClInclude Include="..\src\core\Memory.hpp" />
<ClInclude Include="..\src\core\StringBuilder.hpp" />
<ClInclude Include="..\src\core\StringReader.hpp" />
<ClInclude Include="..\src\core\Util.hpp" />
<ClInclude Include="..\src\cursors.h" />
<ClInclude Include="..\src\diagnostic.h" />
<ClInclude Include="..\src\drawing\drawing.h" />

View File

@ -27,6 +27,7 @@ extern "C" {
}
#include "mixer.h"
#include <cmath>
#include "../core/Util.hpp"
Mixer gMixer;
@ -434,10 +435,10 @@ Mixer::Mixer()
{
effectbuffer = 0;
volume = 1;
for (int i = 0; i < countof(css1sources); i++) {
for (size_t i = 0; i < Util::CountOf(css1sources); i++) {
css1sources[i] = 0;
}
for (int i = 0; i < countof(musicsources); i++) {
for (size_t i = 0; i < Util::CountOf(musicsources); i++) {
musicsources[i] = 0;
}
}
@ -458,7 +459,7 @@ void Mixer::Init(const char* device)
format.channels = have.channels;
format.freq = have.freq;
const char* filename = get_file_path(PATH_ID_CSS1);
for (int i = 0; i < countof(css1sources); i++) {
for (size_t i = 0; i < Util::CountOf(css1sources); i++) {
Source_Sample* source_sample = new Source_Sample;
if (source_sample->LoadCSS1(filename, i)) {
source_sample->Convert(format); // convert to audio output format, saves some cpu usage but requires a bit more memory, optional
@ -481,13 +482,13 @@ void Mixer::Close()
}
Unlock();
SDL_CloseAudioDevice(deviceid);
for (int i = 0; i < countof(css1sources); i++) {
for (size_t i = 0; i < Util::CountOf(css1sources); i++) {
if (css1sources[i] && css1sources[i] != &source_null) {
delete css1sources[i];
css1sources[i] = 0;
}
}
for (int i = 0; i < countof(musicsources); i++) {
for (size_t i = 0; i < Util::CountOf(musicsources); i++) {
if (musicsources[i] && musicsources[i] != &source_null) {
delete musicsources[i];
musicsources[i] = 0;
@ -530,9 +531,9 @@ void Mixer::Stop(Channel& channel)
Unlock();
}
bool Mixer::LoadMusic(int pathId)
bool Mixer::LoadMusic(size_t pathId)
{
if (pathId >= countof(musicsources)) {
if (pathId >= Util::CountOf(musicsources)) {
return false;
}
if (!musicsources[pathId]) {
@ -797,14 +798,14 @@ void Mixer_Init(const char* device)
gMixer.Init(device);
}
void* Mixer_Play_Effect(int id, int loop, int volume, float pan, double rate, int deleteondone)
void* Mixer_Play_Effect(size_t id, int loop, int volume, float pan, double rate, int deleteondone)
{
if (gOpenRCT2Headless) return 0;
if (!gConfigSound.sound) {
return 0;
}
if (id >= countof(gMixer.css1sources)) {
if (id >= Util::CountOf(gMixer.css1sources)) {
return 0;
}
gMixer.Lock();

View File

@ -166,7 +166,7 @@ public:
void Unlock();
Channel* Play(Source& source, int loop, bool deleteondone, bool deletesourceondone);
void Stop(Channel& channel);
bool LoadMusic(int pathid);
bool LoadMusic(size_t pathid);
void SetVolume(float volume);
Source* css1sources[SOUND_MAXID];
@ -201,7 +201,7 @@ extern "C"
#endif
void Mixer_Init(const char* device);
void* Mixer_Play_Effect(int id, int loop, int volume, float pan, double rate, int deleteondone);
void* Mixer_Play_Effect(size_t id, int loop, int volume, float pan, double rate, int deleteondone);
void Mixer_Stop_Channel(void* channel);
void Mixer_Channel_Volume(void* channel, int volume);
void Mixer_Channel_Pan(void* channel, float pan);

20
src/core/Util.hpp Normal file
View File

@ -0,0 +1,20 @@
#ifndef _UTIL_HPP_
#define _UTIL_HPP_
#include <cstdlib>
/**
* Common utility functions.
*/
namespace Util {
// Based on http://www.g-truc.net/post-0708.html
template <typename T, size_t N>
constexpr size_t CountOf(T const (&)[N]) noexcept
{
return N;
}
} // namespace Util
#endif // _UTIL_HPP_

View File

@ -36,6 +36,7 @@ extern "C" {
#include <algorithm>
#include <set>
#include <string>
#include "../core/Util.hpp"
extern "C" {
#include "../config.h"
#include "../game.h"
@ -844,10 +845,10 @@ std::string Network::GenerateAdvertiseKey()
static char hexChars[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
char key[17];
for (int i = 0; i < 16; i++) {
int hexCharIndex = util_rand() % countof(hexChars);
int hexCharIndex = util_rand() % Util::CountOf(hexChars);
key[i] = hexChars[hexCharIndex];
}
key[countof(key) - 1] = 0;
key[Util::CountOf(key) - 1] = 0;
return key;
}

View File

@ -554,10 +554,10 @@ void platform_resolve_user_data_path()
char buffer[MAX_PATH];
buffer[0] = '\0';
log_verbose("buffer = '%s'", buffer);
const char *homedir = getpwuid(getuid())->pw_dir;
platform_posix_sub_user_data_path(buffer, homedir, separator);
log_verbose("OpenRCT2 user data directory = '%s'", buffer);
int len = strnlen(buffer, MAX_PATH);
wchar_t *w_buffer = regular_to_wchar(buffer);

View File

@ -81,7 +81,30 @@ typedef utf16* utf16string;
// Rounds an integer down to the given power of 2. y must be a power of 2.
#define floor2(x, y) ((x) & (~((y) - 1)))
#define countof(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
#ifndef __cplusplus
// in C++ you should be using Util::CountOf
#ifdef __GNUC__
/**
* Force a compilation error if condition is true, but also produce a
* result (of value 0 and type size_t), so the expression can be used
* e.g. in a structure initializer (or where-ever else comma expressions
* aren't permitted).
*/
#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
/* &a[0] degrades to a pointer: a different type from an array */
#define __must_be_array(a) \
BUILD_BUG_ON_ZERO(__builtin_types_compatible_p(typeof(a), typeof(&a[0])))
// based on http://lxr.free-electrons.com/source/include/linux/kernel.h#L54
#define countof(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))
#elif defined (_MSC_VER)
#define countof(arr) _countof(arr)
#else
#define countof(arr) (sizeof(arr) / sizeof((arr)[0]))
#endif // __GNUC__
#endif // __cplusplus
#ifndef _MSC_VER
// use similar struct packing as MSVC for our structs