Skip to content
victor edited this page Aug 8, 2025 · 6 revisions

πŸ›οΈ Smart_Store API guide.

Smart_Store APIs are intuitive, powerful, and highly extensible. With just a single call to addItem(), you can store any object of arbitrary type, automatically registered and ready to use. Every item added inherits the full set of capabilities provided by the ItemManager interface, including tagging, querying, exporting, and state tracking. Whether you're working locally or leveraging global item access, Smart_Store APIs give you modular control and thread-safe operations right out of the box.
Below are practical examples to help you integrate and unleash the full potential of Smart_Store APIs:

Here's a factory-designed pattern managed by Smart_Store.


#include "t_manager/ItemManager.h"
#include "err_log/Logger.hpp"
#include <iostream>
#include <chrono>
#include <thread>
#include <unordered_map>
#include <functional>
#include <memory> 
using namespace std;


class Vehicle {
public:
    virtual void createVehicle() = 0;
};

class Jeep : public Vehicle {     // ----> Jeep class
public:
    void createVehicle() override {
        cout << ":::::::-> Jeep Produced." << endl;
    }
};

class Benz : public Vehicle {    // -----> Benz class
public:
    void createVehicle() override {
        cout << ":::::::-> Benz Produced." << endl;
    }
};

class RollsRoyce : public Vehicle {  // -----> RollsRoyce class
public:
    void createVehicle() override {
        cout << ":::::::-> Rolls-Royce Produced." << endl;
    }
};

class Ferrari : public Vehicle {    // ---> ferrari class
public:
    void createVehicle() override {
        cout << ":::::::-> Ferrari Produced." << endl;
    }
};


class Factory {
public:
    static unique_ptr<Vehicle> vehicleFactory(const string& productType) {
        static unordered_map<string, function<Vehicle* ()>> factoryMap = { // unordered map were new instance of different vehicles are returned as value
            {"benz", []() { return new Benz(); }},
            {"jeep", []() { return new Jeep(); }},
            {"ferrari", []() { return new Ferrari(); }},
            {"rollsroyce", []() { return new RollsRoyce(); }}
        };
        if (factoryMap.count(productType)) {
            return unique_ptr<Vehicle>(factoryMap[productType]());
        }
        return nullptr;
    }
};


void simulateCheck() {                   // This function delays the outputs on the client side.
    cout << "\n\n \t\t::: Checking ";
    for (int i = 0; i <= 4; ++i) {
        this_thread::sleep_for(chrono::milliseconds(500));
        cout << ".";
    }
    cout << endl;
}

class I_Client {
public:
  void garage() { // Here is the client class that displays the data.
      system("cls");
      cout << "\n\n::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::" << endl;
      cout << "*************** Vehicles available ***************\n\n";
      cout << "::: benz" << endl;
      cout << "::: jeep" << endl;
      cout << "::: ferrari" << endl;
      cout << "::: rollsroyce";
      cout << "\n\n::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::" << endl;
      cout << "Enter Product Type: ";
      string productType;
      cin >> productType;

      auto vehicle = Factory::vehicleFactory(productType);
      system("cls");

      simulateCheck(); 

      if (vehicle) {
          vehicle->createVehicle();
          this_thread::sleep_for(chrono::milliseconds(5000));
          garage();
      }
      else {
          cout << "\n\n \t\t::::::: No such product :::::::" << endl;
          this_thread::sleep_for(chrono::milliseconds(5000));
          garage();
      }
    }
};



int main() {
  ItemManager manager;
  auto Item1 = std::make_shared<I_Client>(); 
  manager.addItem(Item1, "car_factory");  // <- Item stored and automatically registered.
  auto item = manager.getItem<I_Client>("car_factory");
  item->garage();  // Start the client interaction

  return 0;
}

Here's another implementation containing other API features of ItemMangement for interaction with Smart_Store:


#include "t_manager/ItemManager.h"
#include "err_log/Logger.hpp"
#include <iostream>
#include <string>

using namespace std;

class HumanBeing {
public:
    virtual void speak() const = 0;
    virtual void walk() const = 0;
    virtual void eat() const = 0;
    virtual ~HumanBeing() = default;
};

// Example derived class 
class Boy : public HumanBeing {
public:
    std::string name;
    int age;

public:
    // If you have a constructor that takes parameters, make sure to define 
    // the default constructor as well to avoid issues.

    Boy(std::string name, int age): name(name), age(age) {}
    Boy() {}
    ~Boy() {}

    void speak() const override {
        LOG_CONTEXT(LogLevel::DISPLAY, "Hello, I am a boy named: " + name +  " I am " + to_string(age) + " years old.", {});
    }

    void walk() const override {
        LOG_CONTEXT(LogLevel::DISPLAY, "I am walking like a boy named " + name+ ".", {});
    }

    void eat() const override {
        LOG_CONTEXT(LogLevel::DISPLAY, "I am eating like a boy named " + name + ".", {});
    }
};

// Example of a girl
class Girl : public HumanBeing {
public:
    std::string name;
    int age;

public:
    // If you have a constructor that takes parameters, make sure to define 
    // the default constructor as well to avoid issues.

    Girl(std::string name, int age): name(name), age(age) {}
    Girl() {}
    ~Girl() {}
   
    void speak() const override {
        LOG_CONTEXT(LogLevel::DISPLAY, "Hello, I am a girl named: " + name +  " I am " + to_string(age) + " years old.", {});
    }

    void walk() const override {
        LOG_CONTEXT(LogLevel::DISPLAY, "I am walking like a girl named " + name + ".", {});
    }

    void eat() const override {
        LOG_CONTEXT(LogLevel::DISPLAY, "I am eating like a girl named " + name + ".", {});
    }
};

int main() {
    ItemManager manager;

    // Add items using constructor
    auto Item1 = std::make_shared<Boy>("Tom", 12);
    auto Item2 = std::make_shared<Girl>("Alice", 10);
    manager.addItem(Item1, "Boy1");
    manager.addItem(Item2, "Girl1");

    // Interact with the Boy by returning the Boy item.
    manager.getItem<Boy>("Boy1")->speak();
    manager.getItem<Boy>("Boy1")->walk();
    manager.getItem<Boy>("Boy1")->eat();

    // Modify Boy
    manager.modifyItem<Boy>("Boy1", [](Boy& item) {
        item.age += 1;
        item.name = "UpdatedTom";
    });

    manager.getItem<Boy>("Boy1")->speak();  // See updated values
    std::cout << "::::::::::::::::::::::::::::::::::::::::::::::::::::::::\n";

    // Interact with Girl by returning the Girl Item
    manager.getItem<Girl>("Girl1")->speak();
    manager.getItem<Girl>("Girl1")->walk();
    manager.getItem<Girl>("Girl1")->eat();

    // Modify Girl
    // This function returns the value for modification or change of the value.
    manager.modifyItem<Girl>("Girl1", [](Girl& item) {
        item.age += 1;
        item.name = "UpdatedAlice";
    });
    
    // This function returns the Item with this tag for accessing its value.
    manager.getItem<Girl>("Girl1")->speak();  // See updated values
    std::cout << "::::::::::::::::::::::::::::::::::::::::::::::::::::::::\n";

    // Undo both modifications
    manager.undo(); // Undo Girl
    manager.undo(); // Undo Boy

    manager.getItem<Boy>("Boy1")->speak();   // Should show "Tom", 12
    manager.getItem<Girl>("Girl1")->speak(); // Should show "Alice", 10
    std::cout << "::::::::::::::::::::::::::::::::::::::::::::::::::::::::\n";

    // Redo both modifications
    manager.redo(); // Redo Boy
    manager.redo(); // Redo Girl

    manager.getItem<Boy>("Boy1")->speak();   // Should show "UpdatedTom", 13
    manager.getItem<Girl>("Girl1")->speak(); // Should show "UpdatedAlice", 11
    std::cout << "::::::::::::::::::::::::::::::::::::::::::::::::::::::::\n";

    return 0;
}

The output:

output one

Another set of APIs for interacting with Smart_Store:


#include "t_manager/ItemManager.h"
#include "err_log/Logger.hpp"
#include <iostream>
#include <string>

using namespace std;

class HumanBeing {
public:
    virtual void speak() const = 0;
    virtual void walk() const = 0;
    virtual void eat() const = 0;
    virtual ~HumanBeing() = default;
};

// Example derived class 
class Boy : public HumanBeing {
public:
    std::string name;
    int age;

public:
    // If you have a constructor that takes parameters, make sure to define 
    // the default constructor as well to avoid issues.
    Boy(std::string name, int age): name(name), age(age) {}
    Boy() {}
    ~Boy() {}

    void speak() const override {
        LOG_CONTEXT(LogLevel::DISPLAY, "Hello, I am a boy named: " + name +  " I am " + to_string(age) + " years old.", {});
    }

    void walk() const override {
        LOG_CONTEXT(LogLevel::DISPLAY, "I am walking like a boy named " + name+ ".", {});
    }

    void eat() const override {
        LOG_CONTEXT(LogLevel::DISPLAY, "I am eating like a boy named " + name + ".", {});
    }
};

// Example of a girl
class Girl : public HumanBeing {
public:
    std::string name;
    int age;

public:
    // If you have a constructor that takes parameters, make sure to define 
    // the default constructor as well to avoid issues.
    Girl(std::string name, int age): name(name), age(age) {}
    Girl() {}
    ~Girl() {}
   
    void speak() const override {
        LOG_CONTEXT(LogLevel::DISPLAY, "Hello, I am a girl named: " + name +  " I am " + to_string(age) + " years old.", {});
    }

    void walk() const override {
        LOG_CONTEXT(LogLevel::DISPLAY, "I am walking like a girl named " + name + ".", {});
    }

    void eat() const override {
        LOG_CONTEXT(LogLevel::DISPLAY, "I am eating like a girl named " + name + ".", {});
    }
};

int main() {
    ItemManager manager;

    // Add items using the constructor
    // All keys must be unique; otherwise, it will throw a type mismatch.
    auto Item1 = std::make_shared<Boy>("Tom", 12);
    auto Item2 = std::make_shared<Girl>("Alice", 10);
    manager.addItem(Item1, "Boy1");
    manager.addItem(Item2, "Girl1");

    // This function retrieves an item by tag and returns a reference to it.
    // It also work like the getItem().
    auto boy = manager.getItemRaw<Boy>("Boy1");
    auto girl = manager.getItemRaw<Girl>("Girl1");
    boy.speak();
    girl.speak();

    // This function deletes the item with tag "Boy1"
    manager.removeByTag("Boy1");

    // This function checks if an item exists by tag and return true or false.
    manager.hasItem("Boy1") ? LOG_CONTEXT(LogLevel::INFO, "Boy1 exists.", {}) : LOG_CONTEXT(LogLevel::INFO, "Boy1 does not exist.", {});
    
    // This function returns the main source of all items in the ItemManager
    const auto& itemStore = manager.getItemMapStore();
    for (const auto& [tag, item] : itemStore) {
        LOG_CONTEXT(LogLevel::INFO, "Item with tag '" + tag + "' has type: " + manager.demangleType(item->getTypeName()) , {});
    }

    return 0;
}

The output:

output two

These APIs are different methods of displaying items in the Smart_Store:

#include "t_manager/ItemManager.h"
#include "err_log/Logger.hpp"
#include <iostream>
#include <string>

using namespace std;

class HumanBeing {
public:
    virtual void speak() const = 0;
    virtual void walk() const = 0;
    virtual void eat() const = 0;
    virtual ~HumanBeing() = default;
};

// Example derived class 
class Boy : public HumanBeing {
public:
    std::string name;
    int age;

public:
    // If you have a constructor that takes parameters, make sure to define 
    // the default constructor as well to avoid issues.
    Boy(std::string name, int age): name(name), age(age) {}
    Boy() {}
    ~Boy() {}

    void speak() const override {
        LOG_CONTEXT(LogLevel::DISPLAY, "Hello, I am a boy named: " + name +  " I am " + to_string(age) + " years old.", {});
    }

    void walk() const override {
        LOG_CONTEXT(LogLevel::DISPLAY, "I am walking like a boy named " + name+ ".", {});
    }

    void eat() const override {
        LOG_CONTEXT(LogLevel::DISPLAY, "I am eating like a boy named " + name + ".", {});
    }
};

// Example of a girl
class Girl : public HumanBeing {
public:
    std::string name;
    int age;

public:
    // If you have a constructor that takes parameters, make sure to define 
    // the default constructor as well to avoid issues.
    Girl(std::string name, int age): name(name), age(age) {}
    Girl() {}
    ~Girl() {}
   
    void speak() const override {
        LOG_CONTEXT(LogLevel::DISPLAY, "Hello, I am a girl named: " + name +  " I am " + to_string(age) + " years old.", {});
    }

    void walk() const override {
        LOG_CONTEXT(LogLevel::DISPLAY, "I am walking like a girl named " + name + ".", {});
    }

    void eat() const override {
        LOG_CONTEXT(LogLevel::DISPLAY, "I am eating like a girl named " + name + ".", {});
    }
};

int main() {
    ItemManager manager;

    // Add items using constructor
    auto Item1 = std::make_shared<Boy>("Tom", 12);
    auto Item2 = std::make_shared<Girl>("Alice", 10);
    manager.addItem(Item1, "Boy1");
    manager.addItem(Item2, "Girl1");
    manager.displayRegisteredDeserializers();
    manager.displayAll();
    manager.displayAllClasses();
    manager.displayByTag("Boy1");
    manager.displayByTag("Girl1");
    std::vector<std::string> tags = {"Boy1", "Girl1"};
    manager.filterByTag(tags);
    manager.sortItemsByTag();
    manager.listRegisteredTypes();
    manager.displayByTag("NonExistentTag");

    return 0;
}

The output:

output three

πŸ›οΈ Smart_Store

::| Development Guide |::

If you encounter any issues and bugs, please reach out via email or GitHub issues.

Clone this wiki locally