Unseen Academy

Different Coding Gems found on the internet

Fast circular ringbuffer for logging(win32)

Separating Interfaces from Implementation

Change Implementation on Compile Time

check for 64bit errors

Tiny Regular Expressions

MultiLine preprocessor strings

Macro with runtime and preprocessortime checks

Easy preprocessor defines


Fast circular ringbuffer for logging(win32)

found here http://preshing.com/20120522/lightweight-in-memory-logging #include <windows.h> #include <intrin.h> namespace Logger { struct Event { DWORD tid; // Thread ID const char* msg; // Message string DWORD param; // A parameter which can mean anything you want }; static const int BUFFER_SIZE = 65536; // Must be a power of 2 extern Event g_events[BUFFER_SIZE]; extern LONG g_pos; inline void Log(const char* msg, DWORD param) { // Get next event index LONG index = _InterlockedIncrement(&g_pos); // Write an event at this index Event* e = g_events + (index & (BUFFER_SIZE - 1)); // Wrap to buffer size e->tid = ((DWORD*) __readfsdword(24))[9]; // Get thread ID e->msg = msg; e->param = param; } } #define LOG(m, p) Logger::Log(m, p) and in a cpp file: namespace Logger { Event g_events[BUFFER_SIZE]; LONG g_pos = -1; }


Separating Interfaces from Implementation

found here http://bitsquid.blogspot.de/2012/03/pimpl-vs-pure-virtual-interfaces.html for c: struct SoundWorld; typedef unsigned SoundInstanceId; SoundWorld *make_sound_world(); void destroy_sound_world(SoundWorld *world); SoundInstanceId play(SoundWorld *world, SoundResource *sound); void stop(SoundWorld *world, SoundInstanceId id); and for the implementation: struct SoundWorld { SoundInstance playing_instances[MAX_PLAYING_INSTANCES]; Matrix4x4 listener_pose; ... }; for c++: class SoundWorld { public: typedef unsigned InstanceId; virtual ~SoundWorld() {} virtual InstanceId play(SoundResource *sound) = 0; virtual void stop(InstanceId id) = 0; static SoundWorld *make(Allocator &a); static void destroy(Allocator &a, SoundWorld *sw); }; and implementation: class SoundWorldImplementation : public SoundWorld { friend class SoundWorld; SoundInstance _playing_instances[MAX_PLAYING_INSTANCES]; Matrix4x4 _listener_pose; SoundWorldImplementation() { ... } virtual InstanceId play(SoundResource *sound) { InstanceId id = allocate_id(); ... } virtual void stop(InstanceId) { ... } // A private method - no declaration necessary. InstanceId allocate_id() { ... } }; SoundWorld *SoundWorld::make(Allocator &a) { return a.make(); } SoundWorld *SoundWorld::destroy(Allocator &a, SoundWorld *sw) { return a.destroy(sw); }


Change Implementation on Compile Time

also known as "compile-time polymorphism", for example for os-dependent stuff: struct TimerServerInterface { //only used for debug stuff to check the interface virtual void func1() = 0; virtual void func2() = 0; }; #ifdef WIN32 #include "win32-stuff.h" typedef TimerServerWin32 TimerServer; #endif TimerServer server; server.func1(); server.func2(); and in (for example) the win32-header: struct TimerServerWin32 #ifdef DEBUG //in debugbuilds the interface gets checked : public TimerServerInterface #endif { void func1() { ... } void func2() { ... } };


check for 64bit errors

"We make sure that our allocations start above the 4 GB line. If every allocation has some bits in the high 32 bits then pointer truncation bugs tend to cause warm fuzzy crashes immediately, and 64-bit cleanliness is easy." found here: http://randomascii.wordpress.com/2012/02/14/64-bit-made-easy/ void ReserveBottomMemory() { #ifdef _WIN64 static bool s_initialized = false; if ( s_initialized ) return; s_initialized = true; // Start by reserving large blocks of address space, and then // gradually reduce the size in order to capture all of the // fragments. Technically we should continue down to 64 KB but // stopping at 1 MB is sufficient to keep most allocators out. const size_t LOW_MEM_LINE = 0x100000000LL; size_t totalReservation = 0; size_t numVAllocs = 0; size_t numHeapAllocs = 0; size_t oneMB = 1024 * 1024; for (size_t size = 256 * oneMB; size >= oneMB; size /= 2) { for (;;) { void* p = VirtualAlloc(0, size, MEM_RESERVE, PAGE_NOACCESS); if (!p) break; if ((size_t)p >= LOW_MEM_LINE) { // We don't need this memory, so release it completely. VirtualFree(p, 0, MEM_RELEASE); break; } totalReservation += size; ++numVAllocs; } } // Now repeat the same process but making heap allocations, to use up // the already reserved heap blocks that are below the 4 GB line. HANDLE heap = GetProcessHeap(); for (size_t blockSize = 64 * 1024; blockSize >= 16; blockSize /= 2) { for (;;) { void* p = HeapAlloc(heap, 0, blockSize); if (!p) break; if ((size_t)p >= LOW_MEM_LINE) { // We don't need this memory, so release it completely. HeapFree(heap, 0, p); break; } totalReservation += blockSize; ++numHeapAllocs; } } // Perversely enough the CRT doesn't use the process heap. Suck up // the memory the CRT heap has already reserved. for (size_t blockSize = 64 * 1024; blockSize >= 16; blockSize /= 2) { for (;;) { void* p = malloc(blockSize); if (!p) break; if ((size_t)p >= LOW_MEM_LINE) { // We don't need this memory, so release it completely. free(p); break; } totalReservation += blockSize; ++numHeapAllocs; } } // Print diagnostics showing how many allocations we had to make in // order to reserve all of low memory, typically less than 200. char buffer[1000]; sprintf_s(buffer, "Reserved %1.3f MB (%d vallocs," "%d heap allocs) of low-memory.\n", totalReservation / (1024 * 1024.0), (int)numVAllocs, (int)numHeapAllocs); OutputDebugStringA(buffer); #endif }


Tiny Regular Expressions

matches regular expressions taken from here: http://www.cs.princeton.edu/courses/archive/spr09/cos333/beautiful.html c matches any literal character c . matches any single character ^ matches the beginning of the input string \$ matches the end of the input string \* matches zero or more occurrences of the previous character /* match: search for regexp anywhere in text */ int match(char *regexp, char *text) { if (regexp[0] == '^') return matchhere(regexp+1, text); do { /* must look even if string is empty */ if (matchhere(regexp, text)) return 1; } while (*text++ != '\0'); return 0; } /* matchhere: search for regexp at beginning of text */ int matchhere(char *regexp, char *text) { if (regexp[0] == '\0') return 1; if (regexp[1] == '*') return matchstar(regexp[0], regexp+2, text); if (regexp[0] == '$' && regexp[1] == '\0') return *text == '\0'; if (*text!='\0' && (regexp[0]=='.' || regexp[0]==*text)) return matchhere(regexp+1, text+1); return 0; } /* matchstar: search for c*regexp at beginning of text */ int matchstar(int c, char *regexp, char *text) { do { /* a * matches zero or more instances */ if (matchhere(regexp, text)) return 1; } while (*text != '\0' && (*text++ == c || c == '.')); return 0; }


MultiLine preprocessor strings

originally taken from a tweet by alex evans #define s(x) #x char *t=s(multi line string!)


Macro with runtime and preprocessortime checks

in a response to linus torvalds challenge found here https://plus.google.com/u/0/102150693225130002912/posts/9gntjh57dXt // Macro that offers run-time and preprocessor-time checks to know if some macros are defined // Assumption: When existing, macros are defined to be 1 // // Compiles and works both under GCC and MSVC (and expected to work under most other environments) // // Response to Linus Torvalds' G+ challenge: https://plus.google.com/u/0/102150693225130002912/posts/9gntjh57dXt // // from David Ramos // kudos to Jean-Noel Avila for simplifying my initial implementation // example: // #define CONFIG_EXISTS 1 // if(is_enabled(CONFIG_DOESNT_EXIST)) // printf("Enabled! RUNTIME\n"); // #if is_enabled(CONFIG_EXISTS) // printf("Enabled! PREPROCESSOR\n"); // #endif #define donothing(...) #define __open ( #define close__ ) /* This macro below is so it works on GCC. In MSVC it would be enough with just doing "#define is_enabled1(x) (donothing __open helper_##x close__) + 0)" */ #define macro_caller(macro, args) macro args #define helper_1 close__ __open 1 #define is_enabled1(x) (macro_caller(donothing, __open helper_##x close__) + 0) #define is_enabled(x) is_enabled1(x)


Easy preprocessor defines

http://www.codersnotes.com/notes/easy-preprocessor-defines // #define BIG_ENDIAN ON // #if USING(BIG_ENDIAN) // ... // #endif // The advantage here is that a macro is forced to either be defined to ON or OFF; if // you don’t define it all you’ll get a compiler error. #define ON 2- #define OFF 1- #define USING(x) ( (x 0) == 2) ofcourse you have to give them better names