mudgangster

Tiny, scriptable MUD client
Log | Files | Refs | README

common.h (3363B)


      1 #pragma once
      2 
      3 #include <stdio.h>
      4 #include <stdint.h>
      5 #include <stddef.h>
      6 #include <stdlib.h>
      7 #include <string.h>
      8 #include <assert.h>
      9 
     10 #include "config.h"
     11 
     12 #include "tracy/Tracy.hpp"
     13 
     14 typedef uint8_t u8;
     15 typedef uint16_t u16;
     16 typedef uint32_t u32;
     17 
     18 #define FATAL( form, ... ) \
     19 	do { \
     20 		printf( "[FATAL] " form, ##__VA_ARGS__ ); \
     21 		abort(); \
     22 	} while( 0 )
     23 
     24 #define STATIC_ASSERT( p ) static_assert( p, #p )
     25 #define ASSERT assert
     26 #define NONCOPYABLE( T ) T( const T & ) = delete; void operator=( const T & ) = delete;
     27 
     28 template< typename T, size_t N >
     29 char ( &ArrayCountObj( const T ( & )[ N ] ) )[ N ];
     30 #define ARRAY_COUNT( arr ) ( sizeof( ArrayCountObj( arr ) ) )
     31 
     32 template< typename T >
     33 constexpr T min( T a, T b ) {
     34 	return a < b ? a : b;
     35 }
     36 
     37 template< typename T >
     38 constexpr T max( T a, T b ) {
     39 	return a > b ? a : b;
     40 }
     41 
     42 template< typename T >
     43 void swap( T & a, T & b ) {
     44 	T t = a;
     45 	a = b;
     46 	b = t;
     47 }
     48 
     49 template< typename To, typename From >
     50 inline To checked_cast( const From & from ) {
     51 	To result = To( from );
     52 	assert( From( result ) == from );
     53 	return result;
     54 }
     55 
     56 inline void * alloc_size( size_t size ) {
     57 	void * ptr = malloc( size );
     58 	if( ptr == NULL ) {
     59 		FATAL( "malloc" );
     60 		abort();
     61 	}
     62 	return ptr;
     63 }
     64 
     65 template< typename T >
     66 T * alloc() {
     67 	return ( T * ) alloc_size( sizeof( T ) );
     68 }
     69 
     70 template< typename T >
     71 T * alloc_many( size_t n ) {
     72 	if( SIZE_MAX / n < sizeof( T ) )
     73 		FATAL( "allocation too large" );
     74 	return ( T * ) alloc_size( n * sizeof( T ) );
     75 }
     76 
     77 template< typename T >
     78 T * realloc_many( T * old, size_t n ) {
     79 	if( SIZE_MAX / n < sizeof( T ) )
     80 		FATAL( "allocation too large" );
     81 	T * res = ( T * ) realloc( old, n * sizeof( T ) );
     82 	if( res == NULL ) {
     83 		FATAL( "realloc" );
     84 		abort();
     85 	}
     86 	return res;
     87 }
     88 
     89 template< typename T >
     90 struct Span {
     91 	T * ptr;
     92 	size_t n;
     93 
     94 	constexpr Span() : ptr( NULL ), n( 0 ) { }
     95 	constexpr Span( T * ptr_, size_t n_ ) : ptr( ptr_ ), n( n_ ) { }
     96 
     97 	// allow implicit conversion to Span< const T >
     98 	operator Span< const T >() { return Span< const T >( ptr, n ); }
     99 	operator Span< const T >() const { return Span< const T >( ptr, n ); }
    100 
    101 	size_t num_bytes() const { return sizeof( T ) * n; }
    102 
    103 	T & operator[]( size_t i ) {
    104 		assert( i < n );
    105 		return ptr[ i ];
    106 	}
    107 
    108 	const T & operator[]( size_t i ) const {
    109 		assert( i < n );
    110 		return ptr[ i ];
    111 	}
    112 
    113 	Span< T > operator+( size_t i ) {
    114 		assert( i <= n );
    115 		return Span< T >( ptr + i, n - i );
    116 	}
    117 
    118 	Span< const T > operator+( size_t i ) const {
    119 		assert( i <= n );
    120 		return Span< const T >( ptr + i, n - i );
    121 	}
    122 
    123 	void operator++( int ) {
    124 		assert( n > 0 );
    125 		ptr++;
    126 		n--;
    127 	}
    128 
    129 	T * begin() { return ptr; }
    130 	T * end() { return ptr + n; }
    131 	const T * begin() const { return ptr; }
    132 	const T * end() const { return ptr + n; }
    133 
    134 	Span< T > slice( size_t start, size_t one_past_end ) {
    135 		assert( start <= one_past_end );
    136 		assert( one_past_end <= n );
    137 		return Span< T >( ptr + start, one_past_end - start );
    138 	}
    139 
    140 	Span< const T > slice( size_t start, size_t one_past_end ) const {
    141 		assert( start <= one_past_end );
    142 		assert( one_past_end <= n );
    143 		return Span< const T >( ptr + start, one_past_end - start );
    144 	}
    145 
    146 	template< typename S >
    147 	Span< S > cast() {
    148 		assert( num_bytes() % sizeof( S ) == 0 );
    149 		return Span< S >( ( S * ) ptr, num_bytes() / sizeof( S ) );
    150 	}
    151 };
    152 
    153 template< typename T >
    154 Span< T > alloc_span( size_t n ) {
    155 	return Span< T >( alloc_many< T >( n ), n );
    156 }