/* DataTypes.cpp : This file contains supplemental generic data types. author: Edward Middleton-Smith project: Shared technology: Libraries feature: Data Types */ // COMMENTS: // METHODS // FUNCTION // VARIABLE DECLARATION + INSTANTIATION // ARGUMENT VALIDATION // METHODS // RETURNS // CLASS METHODS: // FUNCTION // VARIABLE & ATTRIBUTE DECLARATION + INSTANTIATION // ARGUMENT VALIDATION // METHODS // RETURNS // INCLUDES // internal // #include "pch.h" #include "DataTypes.h" // Templates template std::ostream& operator<<(std::ostream& os, T& v) { os << v.ToString(); return os; } template std::ostream& operator<<(std::ostream& os, std::vector& vec) { return printVector(os, vec); } template std::ostream& operator<<(std::ostream& os, FastList& vec) { os << vec.ToString(); return os; } /* template std::ostream& operator<<(std::ostream& os, const std::vector>& vec) { return printVector(os, vec); } */ // Base case: Overload for a 1-dimensional vector template std::ostream& printVector(std::ostream& os, std::vector& vec) { os << "["; for (size_t i = 0; i < vec.size(); ++i) { os << vec[i]; // printVector(os, vec[i]); if (i < vec.size() - 1) { os << ", "; } } os << "]"; return os; } // Recursive case: Overload for n-dimensional vectors template std::ostream& printVector(std::ostream& os, std::vector< std::vector>& vec) { os << "["; for (size_t i = 0; i < vec.size(); ++i) { // Recursively call the printVector function for sub-vectors // os << printVector(vec[i]); // os << printVector(vec.at(i)); printVector(os, vec[i]); if (i < vec.size() - 1) { os << ", "; } } os << "]"; return os; } // LinkedListNode // LinkedList // library123::enumPlusPlusItem::enumPlusPlusItem(std::string name, int index) : name(name), index(index) { }; std::string library123::enumPlusPlusItem::Name() { return this->name; }; int library123::enumPlusPlusItem::Index() { return this->index; }; std::string library123::enumPlusPlusItem::to_string() { return std::format("Name: {}, Value: {}", this->name, this->index); } library123::enumPlusPlus::enumPlusPlus(std::vector enumNames, int iStart) { // FUNCTION // Constructor for enumPlusPlus // ARGUMENT VALIDATION if (enumNames.size() == 0) { library123::ArgVal::ThrowError("Error: no names provided to enum.", true); }; // ATTRIBUTE DECLARATION + INSTANTIATION this->iStart = iStart; this->enums = std::vector(); // {}; // METHODS for (int i = iStart; i < iStart + enumNames.size(); i++) { this->enums.push_back(enumPlusPlusItem(enumNames.at(i), i)); } } std::string library123::enumPlusPlus::to_string() { // FUNCTION // Convert enumPlusPlus object to string representation // VARIABLE DECLARATION + INSTANTIATION std::ostringstream oss; oss << "["; int sz = this->Size(); // METHODS if (sz > 0) { for (int i = 0; i < sz; i++) { oss << ((i == 0) ? "" : ", ") << this->enums.at(i).to_string(); } } oss << "]"; // RETURNS return oss.str(); } int library123::enumPlusPlus::IStart() { return this->iStart; }; int library123::enumPlusPlus::Size() { return this->enums.size(); }; library123::enumPlusPlusItem library123::enumPlusPlus::GetBy(int index, bool suppressErrors) { // FUNCTION // Get enumPlusPlusItem by index // ARGUMENT VALIDATION if (index < 0 || index >= this->Size()) { library123::ArgVal::ThrowError("Error: Invalid index.", suppressErrors); return library123::enumPlusPlusItem("Error", 0); } // RETURNS return this->enums.at(index); } library123::enumPlusPlusItem library123::enumPlusPlus::GetBy(std::string name, bool suppressErrors) { // FUNCTION // Find enumPlusPlusItem by name // VARIABLE DECLARATION + INSTANTIATION int sz = this->Size(); // ARGUMENT VALIDATION if (sz == 0) { library123::ArgVal::ThrowError("Error: Invalid index.", suppressErrors); return library123::enumPlusPlusItem("Error", 0); } // METHODS for (int i = 0; i < sz; i++) { library123::enumPlusPlusItem item = this->enums.at(i); if (item.Name() == name) { return item; } } // RETURNS library123::ArgVal::ThrowError("Error: enumPlusPlusItem not found by name.", suppressErrors); return library123::enumPlusPlusItem("Error", 0); } template bool library123::ArgVal::IsString(const W& value) { return std::is_same::value || std::is_same::value; } /* template typename std::enable_if::value, void>::type std::string ToString(const W& arg) { // method 0 if (HasMethodToString::value) { return arg.to_string(); }; // method 1: fail // return std::to_string(value); // method 2 std::ostream oss; oss << arg; return oss.str(); } */ /* template std::string library123::ArgVal::ToString(S s) { return std::to_string(s); } template std::string library123::ArgVal::ToString(std::vector s) { // method 2 std::ostream oss; int sz = s.size(); oss << "["; for (int i = 0; i < sz; i++) { oss << library123::ArgVal::ToString(s.at(i)); if (i < sz - 1) { oss << ", "; }; } oss << "]"; return oss.str(); } */ /* template std::string library123::ArgVal::ToString(const W& arg) { // method 0 if (HasMethodToString::value) { return arg.to_string(); }; // method 1: fail // return std::to_string(value); // method 2 std::ostream oss; oss << arg; return oss.str(); } template std::string library123::ArgVal::ToString(const std::vector& value) { // method 2 std::ostream oss; int sz = value.size(); oss << "["; for (int i = 0; i < sz; i++) { oss << library123::ArgVal::ToString(value.at(i)); if (i < sz - 1) { oss << ", "; }; } oss << "]"; return oss.str(); } */ template Y library123::ArgVal::ExtractValue(const Y& arg) { if (std::is_pointer::value) { return *arg; }; return arg; } template std::string library123::ArgVal::ErrorHole(const std::vector& v) { return ""; } template std::string library123::ArgVal::ErrorHole2(const std::vector& v1, const std::vector& v2) { return ""; } /* template std::string library123::ArgVal::ErrorMessage(T name, U var, V typeExpected0, V valueExpected, int sizeExpected, bool attrNotVar) { return std::string(""); } */ template std::string library123::ArgVal::ErrorMessage(std::string varName, std::string funcName, T& var, std::string typeExpected, U& valueExpected, bool attrNotVar) { // FUNCTION // Generate error message string // VARIABLE DECLARATION // VARIABLE INSTANTIATION std::string attrVar = attrNotVar ? "attribute" : "variable"; std::string type = typeid(var).name(); std::ostringstream ret; // METHODS // type name size_t found = type.find("["); std::string typeName = type.substr(0, found - 1); size_t foundExpected = typeExpected.find("["); std::string typeNameExpected = typeExpected.substr(0, foundExpected - 1); if (typeName != typeNameExpected) { // return std::format("Error: Invalid {} {} {} data type.\nMethod: {}\nActual type: {}", typeNameExpected, attrVar, varName, funcName, typeName); ret << "Error: Invalid " << typeNameExpected << " " << attrVar << " " << varName << " data type.\nMethod: " << funcName << "\nActual type: " << typeName; return ret.str(); } // value - default // RETURNS // return std::format("Error: Invalid {} {} {}{}.\nMethod: {}Expected: {}.\nActual: {}.", typeNameExpected, attrVar, varName, (var == valueExpected) ? "" : " value", funcName, valueExpected, var); ret << "Error: Invalid " << typeNameExpected << " " << attrVar << " " << varName << (var == valueExpected ? "" : " value") << ".\nMethod: " << funcName << "\nExpected: " << valueExpected << "\nActual: " << var; return ret.str(); } template std::string library123::ArgVal::ErrorMessage(std::string varName, std::string funcName, std::vector& var, std::string typeExpected, std::vector& valueExpected, bool attrNotVar) { // FUNCTION // Generate error message string // VARIABLE DECLARATION // VARIABLE INSTANTIATION std::string attrVar = attrNotVar ? "attribute" : "variable"; std::string type = typeid(var).name(); std::ostringstream ret; // METHODS // type name size_t found = type.find("["); std::string typeName = type.substr(0, found - 1); size_t foundExpected = typeExpected.find("["); std::string typeNameExpected = typeExpected.substr(0, foundExpected - 1); if (typeName != typeNameExpected) { // return std::format("Error: Invalid {} {} {} data type.\nMethod: {}\nActual type: {}", typeNameExpected, attrVar, varName, funcName, typeName); ret << "Error: Invalid " << typeNameExpected << " " << attrVar << " " << varName << " data type.\nMethod: " << funcName << "\nActual type: " << typeName; return ret.str(); } // RETURNS // return std::format("Error: Invalid {} {} {}{}.\nMethod: {}Expected: {}.\nActual: {}.", typeNameExpected, attrVar, varName, " value", funcName, valueExpectedStr, valueActualStr); ret << "Error: Invalid " << typeNameExpected << " " << attrVar << " " << varName << (var == valueExpected ? "" : " value") << ".\nMethod: " << funcName << "\nExpected: "; ret << valueExpected; ret << "\nActual: "; ret << var; return ret.str(); } template std::string library123::ArgVal::ErrorMessage(std::string varName, std::string funcName, const FastList& var, std::string typeExpected, const FastList& valueExpected, bool attrNotVar) { // FUNCTION // Generate error message string // VARIABLE DECLARATION // VARIABLE INSTANTIATION std::string attrVar = attrNotVar ? "attribute" : "variable"; std::string type = typeid(var).name(); std::ostringstream ret; // METHODS // type name size_t found = type.find("["); std::string typeName = type.substr(0, found - 1); size_t foundExpected = typeExpected.find("["); std::string typeNameExpected = typeExpected.substr(0, foundExpected - 1); if (typeName != typeNameExpected) { // return std::format("Error: Invalid {} {} {} data type.\nMethod: {}\nActual type: {}", typeNameExpected, attrVar, varName, funcName, typeName); ret << "Error: Invalid " << typeNameExpected << " " << attrVar << " " << varName << " data type.\nMethod: " << funcName << "\nActual type: " << typeName; return ret.str(); } // RETURNS // return std::format("Error: Invalid {} {} {}{}.\nMethod: {}Expected: {}.\nActual: {}.", typeNameExpected, attrVar, varName, " value", funcName, valueExpectedStr, valueActualStr); ret << "Error: Invalid " << typeNameExpected << " " << attrVar << " " << varName << (var == valueExpected ? "" : " value") << ".\nMethod: " << funcName << "\nExpected: "; /* ret << valueExpected; ret << "\nActual: "; ret << var; */ ret << valueExpected << "\nActual: " << var; return ret.str(); } void library123::ArgVal::ThrowError(std::string errorMsg, bool raiseNotThrow) { // FUNCTION // Report error to console and break programme where necessary // RETURNS std::cerr << errorMsg << std::endl; if (!raiseNotThrow) { throw std::runtime_error(""); } return; } int library123::ArgVal::main() { std::string fName = "ArgumentValidation\\library123::ArgVal::main"; int var = 69; int val = 6; std::string name = "v0"; std::string typeExpected = typeid(val).name(); std::string err_msg = library123::ArgVal::ErrorMessage(name, fName, var, typeExpected, val); std::cerr << err_msg << std::endl; err_msg = library123::ArgVal::ErrorMessage("name", fName, var, typeExpected, val); std::cerr << err_msg << std::endl; std::vector v0 = { 0.0, 1.0, 2.0 }; std::vector v1 = { 0, 1, 3 }; std::vector> v2(3, std::vector(2, 0)); // = { v0; v0; v0 }; std::vector>> v3(3, std::vector>(3, std::vector(3, 0))); // = { v0; v0; v0 }; std::vector>>>> v5(5, std::vector>>>(5, std::vector>>(5, std::vector>(5, std::vector(5, 0))))); // = { v0; v0; v0 }; std::cout << library123::ArgVal::ErrorHole2(v0, v1) << std::endl; typeExpected = typeid(v2).name(); std::cout << "type expected: " << typeExpected << std::endl; err_msg = library123::ArgVal::ErrorMessage(name, fName, v0, typeExpected, v1); // std::string valueActualStr = library123::ArgVal::ToString(var); // err_msg = library123::ArgVal::ErrorHole(v0); std::cerr << err_msg << std::endl; err_msg = library123::ArgVal::ErrorMessage("v2", fName, v2, typeExpected, v2); std::cerr << err_msg << std::endl; err_msg = library123::ArgVal::ErrorMessage("v5", fName, v5, typeExpected, v5); std::cerr << err_msg << std::endl; // valueActualStr = library123::ArgVal::ToString(v2); /* std::ostream o0; o0 << v0; std::cerr << o0.str() << std::endl; std::ostream o1; o1 << v2; std::cerr << o1.str() << std::endl; std::ostream o2; o2 << v3; std::cerr << o2.str() << std::endl; std::ostream o3; o3 << v5; std::cerr << o3.str() << std::endl; // throw std::runtime_error(err_msg); // std::string sName = var.tostring(); int nEWoman = sizeof(eWoman); // / sizeof(static_cast(0)); std::cout << "nEWoman = " << nEWoman << std::endl; for (int i = 0; i < nEWoman; i++) { eWoman ew = static_cast(i); std::cout << std::to_string(ew) << std::endl; } // enumPlusPlus enumPlusPlus eWoman2 = enumPlusPlus({ "" }); std::cout << eWoman2.to_string() << std::endl; enumPlusPlus eWoman3 = enumPlusPlus({ "but cheese", "nipple stains"}); std::cout << eWoman3.to_string() << std::endl; std::cout << eWoman3.GetBy("but cheese").Name() << std::endl; */ return 0; } enum etest { _1, _2, _3 }; struct stest { int id; std::string name; etest eTest; stest(int id, std::string name, etest eTest) : id(id), name(name), eTest(eTest) {}; }; int main() { // test nullptrs int* test = nullptr; std::cout << (!test) << std::endl; std::cout << (true) << std::endl; // test enums PointerType p = PointerType(NEXT); std::cout << p << std::endl; p = PointerType(PREVIOUS); std::cout << p << std::endl; std::cout << p << std::endl; // test std::Vector std::vector ai = { 1, 2, 3 }; // std::cout << "ai: " << ai[-1] << " " << ai[-2] << std::endl; // error - negative indices not allowed // test FastList::Default FastList tmp = FastList::Default(5, 69); std::ostringstream oss; oss << tmp; std::cout << oss.str() << std::endl; // test FastList ToString library123::test_1 test2 = library123::test_1(); // test1:: FastList vt1 = FastList::Default(10, test2); std::cout << test2.ToString() << std::endl; oss = std::ostringstream(); oss << vt1; std::cout << oss.str() << std::endl; int test_3 = tmp[3]; std::cout << "test_3 = " << test_3 << std::endl; library123::test_1 test_4 = vt1[7]; std::cout << "test_4 = " << test_4.ToString() << std::endl; // test duplicate FastList FastList vt2 = vt1; // vt2.Copy(vt1); vt1.Remove(0); // std::cout << "vt2 = " << vt2.ToString() << std::endl; // fail // test struct to string /* stest tester = stest(1, "nudes", etest::_3); std::cout << tester << std::endl; oss = std::ostream(); oss << tester; std::cout << oss.str() << std::endl; */ // test date std::time_t nowtime = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); std::cout << "nowtime = " << nowtime << std::endl; // test int 2 int quantity = (nowtime % 2 == 0) ? 9 : 19; std::vector nugs; for (int i = 0; i < quantity; i++) { nugs.push_back(i); } oss = std::ostringstream(); oss << "nugs = "; oss << nugs; std::cout << oss.str() << std::endl; const int pi = 3; return 0; }