online compiler and debugger for c/c++

code. compile. run. debug. share.
Source Code    Language
#include <stdio.h> #include <functional> #include <map> /* for map */ /** * This class lets you specify access patterns using C++11 lambdas. */ template <typename T> class property { private: std::function<void(const T&)> setFunction; std::function<T()> getFunction; public: /** * Constructor taking the access methods * * @param getf A function to set the value * @param setf A function to get the value */ property(std::function<T()> getf, std::function<void(const T&)> setf) { getFunction = getf; setFunction = setf; } /** * Gets the data */ operator T () { return getFunction(); } /** * Sets the data */ T operator = (const T &i) { setFunction(i); return i; } }; /** * Contains data elements we wish to adorn to a class */ struct Adornment { int Attribute = 8; char* Type = "Unknown"; }; /** * A class to adorn other classes */ class Adorner { private: void* adorned = NULL; Adornment* adornment = NULL; static std::map<void*, Adornment*> adorners; /** * Creates a new instance of an adorner form a pointer * * The adornment will be re-used if the pointer is recognized * * @param pointer A pointer to the adorned instance */ Adorner(void* pointer) { if (Adorner::adorners.find(pointer) == Adorner::adorners.end()) { Adorner::adorners[pointer] = new Adornment(); printf("Adorner created on 0x%p\n", pointer); } else { printf("Adorner re-used on 0x%p\n", pointer); } adornment = Adorner::adorners[pointer]; adorned = pointer; }; public: /** * Erases an Adornment for an instance * * This method searches through the adornments and erases * the one specific to the pointer * * @param pointer A pointer to the adorned instance * @return true if erased, false if unable to erase */ static bool Erase(void* pointer) { if (Adorner::adorners.find(pointer) != Adorner::adorners.end()) { Adornment* a = Adorner::adorners[pointer]; delete a; a = NULL; Adorner::adorners.erase(pointer); printf("Adorner deleted on 0x%p\n", pointer); return true; } return false; } /** * Creates a new instance of an adorner form a pointer * * Calls the class constructor for a general pointer * * @param pointer A pointer to the adorned instance */ template<typename T> Adorner(T* ptr) : Adorner((void*)(ptr)) { printf("Implicit pointer cast using 0x%p\n", ptr); this->adornment->Type = "Unknown"; } /** * Allows for implicit cast to the original type */ template<typename T> operator T*() { return (T*)adorned; } /** * Property to get the "Attribute" adornment */ property<int> Attribute = property<int>([this]() { return this->adornment->Attribute; }, [this](int val) {this->adornment->Attribute = val; }); /** * Property to get the "Type" adornment */ property<char*> Type = property<char*>([this]() { return this->adornment->Type; }, [this](char* type) {this->adornment->Type = type; }); }; /** * Static members are defined out of the class scope. */ std::map<void*, Adornment*> Adorner::adorners; /** * Define a new delete method */ void operator delete(void * p) { if (!Adorner::Erase(p)) { printf("No adorner found on 0x%p\n", p); } free(p); p = NULL; } /** * An example class */ class NormalClass { private: int val = 0; public: /** * Property to get the Value */ property<int> Value = property<int>([this]() { return this->val; }, [this](int val) {this->val = val; }); }; /** * constructor template specialization */ template <> Adorner::Adorner(NormalClass* obj) : Adorner((void*)(obj)) { printf("Implicit NormalClass instance cast using 0x%p\n", (void*)(obj)); this->adornment->Type = "NormalClass"; } /// <summary> /// The main function /// </summary> int main() { // Create a normal class and set its value to something non-default printf("\nCreate a new NormalClass instance and set the Val:\n"); NormalClass* normalClassPointer = new NormalClass(); normalClassPointer->Value = 50; printf("pointer->Value = %d\n", (int)normalClassPointer->Value); // Adorn our NormalClass different ways printf("\nNow add adorners in different ways:\n"); Adorner explicitCastPointer = (Adorner)(normalClassPointer); Adorner implicitCastPointer = normalClassPointer; NormalClass* normalClassPointer2 = new NormalClass(); Adorner implicitCastPointer2 = normalClassPointer2; // Set the value of the adornment attributes explicitCastPointer.Attribute = 5; implicitCastPointer.Attribute = 7; implicitCastPointer2.Attribute = 17; implicitCastPointer2.Type = "Custom"; // Check the adornment property values (they should be the same) printf("\nFor an adorner, all adornment properties should be the same:\n"); printf("explicitCastPointer.Attribute = %d\n", (int)explicitCastPointer.Attribute); printf("explicitCastPointer.Type = %s\n", (char*)explicitCastPointer.Type); printf("implicitCastPointer.Attribute = %d\n", (int)implicitCastPointer.Attribute); printf("implicitCastPointer2.Attribute = %d\n", (int)implicitCastPointer2.Attribute); printf("implicitCastPointer2.Type = %s\n", (char*)implicitCastPointer2.Type); // Now get the original class back form the adorner NormalClass* ncPointerFromImplicitCast = explicitCastPointer; // Even though the value was only set once, both instance and pointer should have the same value printf("pointer->Value = %d\n", (int)ncPointerFromImplicitCast->Value); printf("\nDelete instances believed to have Adorners:\n"); delete normalClassPointer; delete normalClassPointer2; // Make a class we never adorn just so we can see what happens when we delete it printf("\nDelete instnaces having no Adorners:\n"); NormalClass* normalClassPointerNoAdorn = new NormalClass(); delete normalClassPointerNoAdorn; return 0; }

Compiling Program...

Command line arguments:
Standard Input: Interactive Console Text
×

                

                

Program is not being debugged. Click "Debug" button to start program in debug mode.

#FunctionFile:Line
VariableValue
RegisterValue
ExpressionValue