Skip to content
Self-aware struct-like types in C++11
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.

Self-aware structs in C++11

This library provides C++ data types with a user interface like C structs (trivial construction, named accessors, strong types) but with tuple-like metaprogramming abilities, including the ability to query field names as strings and get each field's offset, size, and type.


#include "selfaware.hpp"
#include <tuple>
#include <cstdio>

using namespace selfaware;
using namespace std;

// create a "selfaware identifier"; this is a class template that knows its own
// name and can be used with selfaware::Struct

// instantiate a selfaware struct type
using FooBar = Struct<foo<int>, bar<double>>;

// Struct<T...> looks like a struct to user code; it can be constructed using
// initializer lists, and its fields can be accessed using normal data member
// accessors
FooBar frob(int i)
    FooBar x = {1, 2.0}; += i; += double(i);
    return x;

// However...

// Struct<T...> can also be converted to a tuple and back

tuple<int, double> to_tuple(FooBar const &x) { return x; }
FooBar from_tuple(tuple<int, double> const &x) { return x; }

// Struct<T...> can be unpacked and applied to functions
void show(int foo, double bar) { printf("%x %f\n", foo, bar); }

void showFooBar(FooBar const &fb) { fb.apply(show); }

// Struct<T...>'s field metadata can be iterated, including field name,
// offset, size, and type trait
template<typename> struct show_trait;
template<> struct show_trait<int> {
    static char const* value() { return "int"; }
template<> struct show_trait<double> {
    static char const* value() { return "double"; }

void showFields()
    printf("FooBar has the following fields:\n");
        [](char const *fieldName, unsigned long offset, unsigned long size, char const *typeName) {
            printf("%s: offset %lu, size %lu, type %s\n", fieldName, offset, size, typeName);



How to install

Place selfaware.hpp somewhere it can be included. The library is header-only. A test suite is also included in selfaware-test.cpp, but this does not need to be linked in with user code.


Tested with Clang 3.1 using libc++.


C++11 does not provide a standard mechanism for querying the offsets of fields within non-standard-layout types, so this library relies on nonstandard behavior to do so.

You can’t perform that action at this time.