C/C++ Snippets

Trim Strings

#include <string>

void StrTrim(std::string* psInput)
{
    // trim right
    const std::size_t iLast = psInput->find_last_not_of(" \n\r\t");
    if(iLast != std::string::npos) psInput->erase(iLast+1);

	// trim left
    const std::size_t iFirst = psInput->find_first_not_of(" \n\r\t");
    if(iFirst != std::string::npos) psInput->erase(0, iFirst);
}

Chained Min and Max

#include <utility>

// basic min and max implementations
template <typename T> constexpr T Min(const T& x, const T& y) {return (x < y) ? x : y;}
template <typename T> constexpr T Max(const T& x, const T& y) {return (x > y) ? x : y;}

// extended versions with variadic templates
template <typename T, typename... A> constexpr T Min(const T& x, const T& y, A&&... vArgs)
{return Min(x, Min(y, std::forward<A>(vArgs)...));}
template <typename T, typename... A> constexpr T Max(const T& x, const T& y, A&&... vArgs)
{return Max(x, Max(y, std::forward<A>(vArgs)...));}

Min(a, b, 10.0f, c, Max(d, e));

Open URL with Default Browser

#if defined(_WIN32)
    #include <shellapi.h>   // or windows.h
#else
    #include <cstdlib>
    #include <string>
#endif

bool OpenURL(const char* pcURL)
{
#if defined(_WIN32)

    // open on Windows
    if(int(ShellExecute(NULL, "open", pcURL, NULL, NULL, 1)) > 32) return true;

#elif defined(__linux__)

    // open on Linux
    if(system(NULL)) if(!system((std::string("xdg-open ") + pcURL).c_str())) return true;

#else

    // try to open on everything else (e.g. OSX)
    if(system(NULL)) if(!system((std::string("open ") + pcURL).c_str())) return true;

#endif

	// error
    return false;
}

Create Folder Tree

#if defined(_WIN32)
	#include <fileapi.h>   // or windows.h or winbase.h
	#define CreateFolder(p) CreateDirectory(p, NULL)
#else
	#include <sys/stat.h>
    #define CreateFolder(p) mkdir(p, S_IRWXU)
#endif

#include <string>

void CreateFolderTree(const std::string& sPath)   // "f1/f2/" and "f1/f2/file.txt" are valid
{												  // "f1/f2" creates only folder f1
    std::size_t iPos = 0;

	// loop through path
	while((iPos = sPath.find_first_of("/\\", iPos+2)) != std::string::npos)   // "f1" -> "f1/f2" -> "f1/f2/f3"
    {
        // create subfolder
        CreateFolder(sPath.substr(0, iPos).c_str());
    }
}

Not so Linear Interpolations

#include <cmath>

template <typename T> constexpr T Lerp(const T& x, const T& y, const float& s)noexcept       
{return x + (y - x) * s;}   // constexpr and noexcept are optional

#define PI 				   (3.1415926535897932384626433832795f)
#define LERP(x,y,s) 	   Lerp(x, y, s)							// ## ## ## ## ##
#define LERP_SMOOTH(x,y,s) Lerp(x, y, 0.5f-0.5f*std::cos((s)*PI))   // ### ## # ## ###
#define LERP_BREAK(x,y,s)  Lerp(x, y, std::sin((s)*0.5f*PI)) 		// # ## ## ### ###

Other String Comparisons

#include <cctype>

// constexpr string comparison
constexpr bool StrCmpConst(const char* s, const char* t)
{return *s ? (*s == *t) && StrCmpConst(s+1, t+1) : !*t;}

// normal string comparison with wildcards (* = range, ? = single char)
bool StrCmpLike(const char*  s, const char* t)
{return (*t == '*') ? StrCmpLike(s, t+1) || (*s && StrCmpLike(s+1, t)) :
		*s ? ((*t == '?') || (toupper(*s) == toupper(*t))) && StrCmpLike(s+1, t+1) : !*t;}

static_assert(StrCmpConst(MY_STRING_1, MY_STRING_2), "Error Message");
StrCmpLike("This dog will be found", "*dog*will b? Found") == true;

Check File Existence

#if defined(_WIN32)
    #include <fileapi.h>   // or windows.h or winbase.h
#elif defined(__linux__)
    #include <sys/stat.h>
#else
    #include <cstdio>
#endif

bool FileExists(const char* pcPath)
{
#if defined(_WIN32)

    // quick Windows check
    return (GetFileAttributes(pcPath) == INVALID_FILE_ATTRIBUTES) ? false : true;
    
#elif defined(__linux__)

    // quick Linux check (with POSIX)
    struct stat oBuffer;
    return stat(pcPath, &oBuffer) ? false : true;
    
#else

    // open file
    std::FILE* pFile = std::fopen(pcPath, "r");
    if(pFile)
    {
        // file exists
        std::fclose(pFile);
        return true;
    }
    return false;
    
#endif
}

Portable For-Each

#define FOR_EACH(i,c)     for(auto i = (c).begin(),  i ## __e = (c).end();  i != i ## __e; ++i)
#define FOR_EACH_REV(i,c) for(auto i = (c).rbegin(), i ## __e = (c).rend(); i != i ## __e; ++i)

std::vector<int> myVector;
FOR_EACH(it, myVector) *it += 10;

Dynamic For-Each

#define FOR_EACH_DYN(i,c) for(auto i = (c).begin(), i ## __e = (c).end(); i != i ## __e; )
#define DYN_KEEP(i)       {++i;}
#define DYN_REMOVE(i,c)   {i = (c).erase(i); i ## __e = (c).end();}

std::vector<int> myVector;
FOR_EACH_DYN(it, myVector)
{
    if(*it > 10)
		DYN_REMOVE(it, myVector)   // remove object and continue iteration
    else
		DYN_KEEP(it)			   // don't remove object and continue
}

Disable Copy and Heap Construction

#define DISABLE_COPY(c) \
    c(const c&);        \
    c& operator = (const c&);

#define DISABLE_HEAP                      \
    void* operator new   (size_t);        \
    void* operator new   (size_t, void*); \
    void* operator new[] (size_t);        \
    void* operator new[] (size_t, void*);

class myClass
{
private:   // hide functions
    DISABLE_COPY(myClass)
    DISABLE_HEAP
};

// extendable with explicit delete e.g.
c(const c&) = delete;

Get Array Size

#if !defined(ARRAY_SIZE)
    #if !defined(__cplusplus)

        // simple C macro
        #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))

    #else

        // pointer-safe C++ template macro
        template <typename T, std::size_t iSize> char (&__ARRAY_SIZE(T (&)[iSize]))[iSize];
        #define ARRAY_SIZE(a) (sizeof(__ARRAY_SIZE(a)))

    #endif
#endif

Safely Delete Pointers

#define SAFE_DELETE(p)       {if(p) {delete   (p); (p) = NULL;}}
#define SAFE_DELETE_ARRAY(p) {if(p) {delete[] (p); (p) = NULL;}}

Maus Games


© 2012-now Martin Mauersics
This email address is being protected from spambots. You need JavaScript enabled to view it. - Legal Notice