← All posts

C++ Tricks

Call constructor on already allocated memory #

#include <new>
Foo* foo = new (your_memory_address_here) Foo ();

Memory Stripes #

#include <stdio.h>
#include <cstdlib>
struct v3 {
	float x, y, z;
	v3() : x(1), y(2), z(3) {}
};
v3* p_arr;
const int count = 10;
int main(int argc, const char* argv[]) {
	p_arr = new v3[count];
	srand(1);
	const int stride = 3;
	
	float* p_x = &p_arr->x;
	float* p_y = &p_arr->y;
	float* p_z = &p_arr->z;
	for (int i = 0; i < count; i ++)
	{
		int idx = i * stride;
		printf("%f, %f, %f \n", p_x[idx], p_y[idx], p_z[idx]);
	}
	printf("- - - - - -\n");
	
	for (int i = 0, l = count * stride; i < l; i += stride) {
		printf("%f, %f, %f \n", p_x[i], p_y[i], p_z[i]);
	}
	
    delete[] p_arr;
	return 0;
}

Currying with std::bind #

void my_function(int x, int y, int z) {
	printf("Called my_function with (%d, %d, %d)\n", x, y, z);
}
int main () {
    my_function(1, 2, 3);
    
    auto my_function2 = std::bind(my_function, 1, std::placeholders::_1, std::placeholders::_2);
    my_function2(77, 666);
    
    auto my_function3 = std::bind(my_function2, std::placeholders::_1, 666);
    my_function3(88);
    
    auto my_function4 = std::bind(my_function, 1, std::placeholders::_1, 999);
    my_function4(6969696);
}

Bit shifting union #

struct Color
{
	union
	{
		unsigned int RGBA = 0;
		struct {
			unsigned char A;
			unsigned char B;
			unsigned char G;
			unsigned char R;
		};
	};
};
	Color c;
	c.R = 166;
	c.G = 44;
	c.B = 22;
	c.A = 255;
	printf("RGBA: %d\n", c.RGBA);
	unsigned char Rout = (c.RGBA & 0xff000000) >> 24;
	unsigned char Gout = (c.RGBA & 0x00ff0000) >> 16;
	unsigned char Bout = (c.RGBA & 0x0000ff00) >> 8;
	unsigned char Aout = (c.RGBA & 0x000000ff) >> 0;
	printf("R: %d => %d\n", c.R, Rout);
	printf("G: %d => %d\n", c.G, Gout);
	printf("B: %d => %d\n", c.B, Bout);
	printf("A: %d => %d\n", c.A, Aout);
	c.RGBA = 0x0;
	c.RGBA = 0x110011ff;
	printf("R: %d\n", c.R);
	printf("G: %d\n", c.G);
	printf("B: %d\n", c.B);
	printf("A: %d\n", c.A);

Bitmasks #

Bitmasking is a technique used to perform operations at the bit level. Leveraging bitmasks often leads to faster runtime complexity and helps limit memory usage

- Test kth bit: s & (1 << k);
- Set kth bit: s |= (1 << k);
- Turn off kth bit: s &= ~(1 << k);
- Toggle kth bit: s ^= (1 << k);
- Multiple by 2n: s << n;
- Divide by 2n: s >> n;
- Intersection: s & t;
- Union: s | t;
- Set Subtraction: s & ~t;
- Extract lowest set bit: s & (-s);
- Extract lowest unset bit: ~s & (s + 1);
- Swap Values: x ^= y; y ^= x; x ^= y;

Align memory on boundary #

inline uint32 Align256( uint32 memory_size ) {  
    return ( memory_size + 255 ) & ~255;  
}  
  
inline uint32 Align16( uint32 memory_size ) {  
    return ( memory_size + 15 ) & ~15;  
}

#define __align_16 __declspec(align(16))
__align_16 struct my_struct {
	float x, y, z, w;
};
struct my_struct_2 {
	float x, y, z, w;
} __align_16;

Calculate Mip Map Count #

uint32 CalculateMipMapLevels( uint32 width, uint32 height ) {  
    return 1 + static_cast<uint32>(floor(log2(std::max(width, height))));  
}

Member offset in bytes #

struct Test {
	float x, z, y;
};

auto offset_in_bytes = unsigned int(&(((Test*)0)->z));

Negative int indexing #

  • Use positive/negative int32 values in same field to represent different meanings
  • Negative index (-1 remaps to start at 0)
int32_t Index = -1;
int32_t NegativeIndex = (-1 -Index);
int32_t NegativeIndex = ~Index;