Created
November 30, 2023 22:27
-
-
Save srele96/603b62285d921ea40399118e8b2548a5 to your computer and use it in GitHub Desktop.
You are given a sequence of operations to perform on a list of mixed data types. The data types can include integers, strings, and floating-point numbers. Each operation will specify the type of data it should be applied to and a specific action to perform. Your task is to process these operations efficiently using type erasure in C++.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <memory> | |
#include <vector> | |
class object_ { | |
private: | |
struct concept_ { | |
virtual void process(const std::string& p_value) = 0; | |
virtual void out(std::ostream& p_ostream) const = 0; | |
virtual ~concept_() = default; | |
}; | |
template <typename T> | |
struct model_ : concept_ { | |
model_(const T& p_object) : m_object{p_object} {} | |
void process(const std::string& p_value) override { | |
m_object.process(p_value); | |
} | |
void out(std::ostream& p_ostream) const override { | |
m_object.out(p_ostream); | |
} | |
T m_object; | |
}; | |
std::shared_ptr<concept_> m_object; | |
public: | |
template <typename T> | |
object_(T&& p_object) | |
: m_object{std::make_shared<model_<T>>(std::forward<T>(p_object))} {} | |
// So any object_ is only processable, and that's it? Did I get it right? | |
void process(const std::string& p_value) { m_object->process(p_value); } | |
void out(std::ostream& p_ostream) const { m_object->out(p_ostream); } | |
}; | |
class integer_ { | |
private: | |
int m_value; | |
public: | |
integer_(const std::string& p_value) : m_value{std::stoi(p_value)} {} | |
void process(const std::string& p_value) { m_value += std::stoi(p_value); } | |
void out(std::ostream& p_ostream) const { p_ostream << m_value << "\n"; } | |
}; | |
class string_ { | |
private: | |
std::string m_value; | |
public: | |
string_(const std::string& p_value) : m_value{p_value} {} | |
void process(const std::string& p_value) { m_value += p_value; } | |
void out(std::ostream& p_ostream) const { p_ostream << m_value << "\n"; } | |
}; | |
class float_ { | |
private: | |
float m_value; | |
public: | |
float_(const std::string& p_value) : m_value{std::stof(p_value)} {} | |
void process(const std::string& p_value) { m_value *= std::stof(p_value); } | |
void out(std::ostream& p_ostream) const { p_ostream << m_value << "\n"; } | |
}; | |
int main() { | |
int t; | |
std::cin >> t; | |
std::vector<std::pair<std::string, object_>> pairs; | |
while (t-- > 0) { | |
// Doesn't matter as long as it produces the expected output. | |
std::string operation, type, value; | |
std::cin >> operation >> type >> value; | |
if (operation == "Add") { | |
if (type == "int") { | |
pairs.push_back({"int", integer_{value}}); | |
} else if (type == "string") { | |
pairs.push_back({"string", string_{value}}); | |
} else if (type == "float") { | |
pairs.push_back({"float", float_{value}}); | |
} | |
} else if (operation == "Process") { | |
for (auto& pair : pairs) { | |
if (pair.first == type) { | |
pair.second.process(value); | |
} | |
// Questions from the state of confusion: | |
// | |
// How should the generic container process the data? | |
// How should the public API look like? | |
} | |
} | |
} | |
for (const auto& pair : pairs) { | |
pair.second.out(std::cout); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment