Jump to content

  • Log In with Google      Sign In   
  • Create Account

Banner advertising on our site currently available from just $5!

1. Learn about the promo. 2. Sign up for GDNet+. 3. Set up your advert!

Sweet Snippets - Public free and open repository of game development source


[Userdata] Type-checking void* wrapper

Tags: C++ C++11 void* RTTI
A wrapper around void* for passing unknown data types of any size. Asserts upon retrieval if the type you are trying to retrieve does not match the type you originally gave. Does not take ownership of the data.
userdata.h - The userdata class itself.
#pragma once

#include <typeinfo>
#include <cassert>
//Holds any type of user-given pointer that can be cast to void, and does run-time checks on the type of the data when retrieving it.
//Ownership is *not* taken. It is the original owner's responsibillity to ensure the lifetime of the object when
//someone tries to retrieve the pointer later. The Userdata class itself never de-references the pointer.
class Userdata
        Userdata() = default;
        template<typename UserType>
        Userdata(UserType *data)
        //Sets a user-spe
        template<typename UserType>
        void Set(UserType *data)
                //Save the pointer (cast to void*), and the type's RTTI information, so we can validate on retrieval.
                this->type_info = &typeid(UserType);
                this->userdata = data;
        template<typename UserType>
        UserType *Get()
                //Validate that we've actually set *anything*.
                assert(this->type_info && "We never set any data, so we can't retrieve any.");
                //Validate that we are getting the same type that we initially set.
                assert((*this->type_info) == typeid(UserType) && "The types don't match - we can't retrieve the userdata safely.");
                return static_cast<UserType*>(this->userdata);
        void Reset()
                this->type_info = nullptr;
                this->userdata = nullptr;
        //A pointer to the global compiler-specific (but standardized) type_info for this type (the type that Userdata's void* points to).
        //C++11 guarantees that "The lifetime of the object referred to by [typeid()'s return value] extends to the end of the program." (N3337 5.2.8)
        const std::type_info *type_info = nullptr; 
        //A pointer to the user-defined data.
        void *userdata = nullptr;

main.cpp - Example usage
#include <iostream>
#include <string>
#include "Userdata.h"
int main()
    int myInt = 357;
    float myFloat = 7.53f;
    std::string myString = "This is a test";
    Userdata userdataA(&myString);
    Userdata userdataB;
    int *intPtr = userdataB.Get<int>();
    std::cout << "int:\t\t" << *(intPtr) << " (should be " << myInt << ")" << std::endl;
    userdataB.Set(&myFloat); //Overwrites the first pointer set.
    //Asserts, because it's the wrong type.
    //char *test = userdataB.Get<char>();
    std::cout << "std::string:\t\"" << *(userdataA.Get<std::string>()) << "\" (should be \"" << myString << "\")" << std::endl;
    std::cout << "float:\t\t"     << *(userdataB.Get<float>())       << " (should be " << myFloat  << ")" << std::endl;
    return 0;

. -