mikejsavage.co.uk • About • Archive • RSS • Thanks for blocking ads! Blocking ads owns: AdGuard for Safari / uBlock Origin for everything else
C++20's source_location is dogshit:
> cat a.cpp
#include <source_location>
> cl.exe /std:c++20 a.cpp /P
Microsoft (R) C/C++ Optimizing Compiler Version 19.36.32534 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
a.cpp
> wc -l a.i
6736 a.i
> g++ -E a.cpp -std=c++20 | wc -l
99
> clang++ -E a.cpp -std=c++20 | wc -l
460
but the compilers were kind enough to all use the same intrinsics, so the DIY implementation is trivial:
// zero headers required!
struct SourceLocation {
const char * file;
int line;
const char * function;
};
constexpr SourceLocation CurrentSourceLocation( const char * file_ = __builtin_FILE(), int line_ = __builtin_LINE(), const char * function_ = __builtin_FUNCTION() ) {
return {
.file = file_,
.line = line_,
.function = function_,
};
}
Now you can throw out your old allocation macros:
// before
#define ALLOC( a, T ) ( ( T * ) ( a )->allocate( sizeof( T ), alignof( T ), __PRETTY_FUNCTION__, __FILE__, __LINE__ ) )
// after
template< typename T >
T * Alloc( Allocator * a, SourceLocation src = CurrentSourceLocation() ) {
return ( T * ) a->allocate( sizeof( T ), alignof( T ), src );
}
and also update helper functions to have useful source info:
template< typename T >
Span< T > CloneSpan( Allocator * a, Span< T > span, SourceLocation src = CurrentSourceLocation() ) {
Span< T > copy = AllocSpan< T >( a, span.n, src );
memcpy( copy.ptr, span.ptr, span.num_bytes() );
return copy;
}
// const variant because templates don't do implicit casts
template< typename T >
Span< T > CloneSpan( Allocator * a, Span< const T > span, SourceLocation src = CurrentSourceLocation() ) {
Span< T > copy = AllocSpan< T >( a, span.n, src );
memcpy( copy.ptr, span.ptr, span.num_bytes() );
return copy;
}