569 lines
13 KiB
C++
569 lines
13 KiB
C++
#pragma once
|
|
/*
|
|
card.h : This is the header file for DataTypes.cpp
|
|
|
|
author: Edward Middleton-Smith
|
|
|
|
project: Shared
|
|
technology: Libraries
|
|
feature: Data Types header file
|
|
*/
|
|
|
|
#ifndef DATA_TYPES_H
|
|
#define DATA_TYPES_H
|
|
|
|
// IMPORTS
|
|
// internal
|
|
// #include <pch.h>
|
|
// external
|
|
#include <iostream>
|
|
#include <list>
|
|
#include <vector>
|
|
#include <sstream>
|
|
#include <stdexcept>
|
|
#include <format>
|
|
#include <type_traits>
|
|
#include <string>
|
|
#include <cstddef>
|
|
#include <concepts>
|
|
#include <ostream>
|
|
|
|
// TEMPLATE OBJECTS
|
|
template<typename W>
|
|
concept Stringable = requires(W w)
|
|
{
|
|
{ std::to_string(w) } -> std::convertible_to<std::string>;
|
|
} ||
|
|
requires(W w)
|
|
{
|
|
{ w } -> std::convertible_to<std::string>;
|
|
} ||
|
|
requires(W w)
|
|
{
|
|
{ w.ToString() } -> std::convertible_to<std::string>;
|
|
};
|
|
template<typename W>
|
|
concept HasToString = requires(W w)
|
|
{
|
|
{ w.ToString() } -> std::convertible_to<std::string>;
|
|
};
|
|
|
|
template<Stringable T>
|
|
class FastList
|
|
{
|
|
public:
|
|
FastList() {};
|
|
void PushBack(T item)
|
|
{
|
|
this->aList.push_back(item);
|
|
this->index.push_back(std::prev(this->aList.end()));
|
|
}
|
|
// T* GetItem(int index)
|
|
// std::list<T>::iterator GetItem(int index)
|
|
const T& operator[](std::size_t i) const
|
|
{
|
|
return *index[i];
|
|
// method 1
|
|
/*
|
|
int szList = this->index.size();
|
|
if (szList == 0) { return nullptr; };
|
|
index = std::max(0, std::min(szList - 1, index));
|
|
return this->index[index];
|
|
*/
|
|
}
|
|
T& operator[](std::size_t i)
|
|
{
|
|
return *index[i];
|
|
}
|
|
/*
|
|
FastList<T>& operator=(FastList<T> original)
|
|
{
|
|
// if (this == &original) { return *this; }
|
|
size_t n = original.Size();
|
|
FastList<T> duplicate;
|
|
this.aList = duplicate.aList;
|
|
this.index = duplicate.index;
|
|
if (n == 0) { return duplicate; }
|
|
for (size_t i = 0; i < n; i++)
|
|
{
|
|
this->PushBack(original[i]);
|
|
}
|
|
return &this;
|
|
}
|
|
*/
|
|
void Copy(FastList<T> original)
|
|
{
|
|
size_t n = original.Size();
|
|
FastList<T> duplicate;
|
|
this->aList = std::list<T>();
|
|
this->index = std::vector<typename std::list<T>::iterator>();
|
|
/*
|
|
this->aList = duplicate->aList;
|
|
this->index = duplicate->index;
|
|
*/
|
|
if (n == 0) { return; }
|
|
for (size_t i = 0; i < n; i++)
|
|
{
|
|
this->PushBack(original[i]);
|
|
}
|
|
}
|
|
void Insert(T item, int i)
|
|
{
|
|
int szList = this->index.size();
|
|
i = std::max(0, std::min(szList - 1, i));
|
|
// std::list<T>::iterator middle = std::next(this->aList.begin(), index);
|
|
auto middle = std::next(this->aList.begin(), i);
|
|
this->aList.insert(middle, item);
|
|
this->index.insert(i, item);
|
|
}
|
|
void Remove(int i)
|
|
{
|
|
int szList = this->index.size();
|
|
if (i < -szList || i >= szList) { return; };
|
|
if (i < 0)
|
|
{
|
|
i = szList + i;
|
|
}
|
|
// std::list<T>::iterator middle = std::next(this->aList.begin(), index);
|
|
auto middle = std::next(this->aList.begin(), i);
|
|
this->aList.erase(middle);
|
|
// this->index.erase(i);
|
|
// this->index.erase()
|
|
}
|
|
std::string ToString()
|
|
{
|
|
std::ostringstream oss;
|
|
oss << "FastList" << std::endl;
|
|
int szList = this->index.size();
|
|
if (szList > 0)
|
|
{
|
|
oss << "Items:" << std::endl;
|
|
for (int i = 0; i < szList; i++)
|
|
{
|
|
// oss << &this->GetItem(i) << std::endl;
|
|
oss << *index[i] << std::endl;
|
|
}
|
|
}
|
|
return oss.str();
|
|
}
|
|
void Swap(int i1, int i2)
|
|
{
|
|
int nCard = this->index.size();
|
|
i1 = std::min(std::max(0, i1), nCard);
|
|
i2 = std::min(std::max(0, i2), nCard);
|
|
// std::swap(this->aList[i1], this->aList[i2]);
|
|
// std::swap(this->index[i1], this->index[i2]);
|
|
// std::list<T> tmpList;
|
|
// std::vector<typename std::list<T>::iterator> tmpI;
|
|
// std::list<T>::iterator tmpI = this->index.at(i1);
|
|
/*
|
|
T* tmp1 = this->GetItem(i1);
|
|
T* tmp2 = this->GetItem(i2);
|
|
*/
|
|
T tmp1 = *this->index[i1];
|
|
T tmp2 = *this->index[i2];
|
|
this->Remove(i1);
|
|
this->Insert(tmp2, i1);
|
|
this->Remove(i2);
|
|
this->Insert(tmp1, i2);
|
|
}
|
|
std::size_t Size() const
|
|
{
|
|
return this->index.size();
|
|
}
|
|
// std::vector<typename std::list<T>::iterator> Index()
|
|
auto Index()
|
|
{
|
|
return this->index;
|
|
}
|
|
bool operator==(FastList<T> fl2)
|
|
{
|
|
int n1 = this->Size();
|
|
int n2 = fl2.Size();
|
|
if (n1 != n2) { return false; }
|
|
for (int i = 0; i < n1; i++)
|
|
{
|
|
if (this[i] != fl2[i]) { return false; }
|
|
}
|
|
return true;
|
|
}
|
|
// std::vector<typename std::list<T>::iterator> index;
|
|
static FastList<T> Default(int nElem, T vDefault)
|
|
{
|
|
nElem = std::max(0, nElem);
|
|
FastList<T> v;
|
|
if (nElem > 0)
|
|
{
|
|
for (int i = 0; i < nElem; i++)
|
|
{
|
|
v.PushBack(vDefault);
|
|
}
|
|
}
|
|
return v;
|
|
}
|
|
private:
|
|
std::list<T> aList;
|
|
std::vector<typename std::list<T>::iterator> index;
|
|
};
|
|
|
|
|
|
// Base case
|
|
template <typename T>
|
|
std::ostream& operator<<(std::ostream& os, std::vector<T>& vec);
|
|
template <typename T>
|
|
std::ostream& operator<<(std::ostream& os, FastList<T>& vec);
|
|
/*
|
|
template <typename T>
|
|
std::ostream& operator<<(std::ostream& os, const std::vector<std::vector<T>>& vec);
|
|
*/
|
|
// Base case: Overload for a 0-dimensional vector element
|
|
template <typename T>
|
|
std::ostream& printVector(std::ostream& os, T& var) {
|
|
os << var;
|
|
return os;
|
|
}
|
|
// Base case: Overload for a 1-dimensional vector
|
|
template <typename T>
|
|
std::ostream& printVector(std::ostream& os, std::vector<T>& vec);
|
|
// Recursive case: Overload for n-dimensional vectors
|
|
template <class T>
|
|
std::ostream& printVector(std::ostream& os, std::vector< std::vector<T>>& vec);
|
|
|
|
// Overload the equality operator (==) for std::vector
|
|
template <typename T, typename U>
|
|
bool areVectorsEqual(const std::vector<T>& v1, const std::vector<U>& v2) { return false; }
|
|
template <typename T>
|
|
bool areVectorsEqual(const std::vector<T>& v1, const std::vector<T>& v2)
|
|
{
|
|
if (v1.size() != v2.size())
|
|
{
|
|
return false; // Vectors have different sizes, so they can't be equal.
|
|
}
|
|
for (size_t i = 0; i < v1.size(); ++i)
|
|
{
|
|
auto i1 = v1[i];
|
|
auto i2 = v2[i];
|
|
if (!(i1 == i2))
|
|
// if (!(v1[i] == v2[i]))
|
|
// if (!(v1.at(i) == v2.at(i)))
|
|
{
|
|
return false; // Elements at the same index are different, so vectors are not equal.
|
|
}
|
|
}
|
|
return true; // All elements are equal, so vectors are equal.
|
|
}
|
|
template <typename T>
|
|
bool areVectorsEqual(const std::vector<std::vector<T>>& v1, const std::vector<std::vector<T>>& v2)
|
|
{
|
|
if (v1.size() != v2.size())
|
|
{
|
|
return false; // Vectors have different sizes, so they can't be equal.
|
|
}
|
|
for (size_t i = 0; i < v1.size(); ++i)
|
|
{
|
|
/*
|
|
auto i1 = v1[i];
|
|
auto i2 = v2[i];
|
|
if (!(i1 == i2))
|
|
*/
|
|
if (!areVectorsEqual(v1[i], v2[i]))
|
|
// if (!(v1[i] == v2[i]))
|
|
// if (!(v1.at(i) == v2.at(i)))
|
|
{
|
|
return false; // Elements at the same index are different, so vectors are not equal.
|
|
}
|
|
}
|
|
return true; // All elements are equal, so vectors are equal.
|
|
}
|
|
template <typename T>
|
|
bool operator==(const std::vector<T>& v1, const std::vector<T>& v2)
|
|
{
|
|
return areVectorsEqual(v1, v2);
|
|
}
|
|
template <typename T>
|
|
bool operator==(const std::vector<std::vector<T>>& v1, const std::vector<std::vector<T>>& v2)
|
|
{
|
|
return areVectorsEqual(v1, v2);
|
|
}
|
|
template <typename T, typename U>
|
|
bool operator==(const std::vector<T>& v1, const std::vector<U>& v2)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
|
|
enum PointerType
|
|
{
|
|
NEXT,
|
|
PREVIOUS
|
|
};
|
|
|
|
|
|
template<typename T>
|
|
class LinkedListNode
|
|
{
|
|
public:
|
|
LinkedListNode(T node, T* nodeNext, T* nodePrev)
|
|
{
|
|
this->node = node;
|
|
this->nodeNext = nodeNext;
|
|
this->nodePrev = nodePrev;
|
|
}
|
|
void SetNode(T node)
|
|
{
|
|
this->node = node;
|
|
}
|
|
void SetPointer(T* ptr, PointerType ptrType)
|
|
{
|
|
if (ptrType == PointerType(NEXT))
|
|
{
|
|
this->nodeNext = ptrType;
|
|
}
|
|
else
|
|
{
|
|
this->nodePrev = ptrType;
|
|
}
|
|
}
|
|
LinkedListNode* GetPointer(PointerType ptrType)
|
|
{
|
|
if (ptrType == PointerType(NEXT))
|
|
{
|
|
return &this->nodeNext;
|
|
}
|
|
else
|
|
{
|
|
return &this->nodePrev;
|
|
}
|
|
}
|
|
private:
|
|
T node;
|
|
T* nodeNext;
|
|
T* nodePrev;
|
|
};
|
|
|
|
|
|
//template<typename T>
|
|
//class LinkedList
|
|
//{
|
|
//public:
|
|
// LinkedList() : head(nullptr), tail(nullptr) {};
|
|
// LinkedList(LinkedListNode<T>* head) : head(head) {};
|
|
// void PushBack(T node)
|
|
// {
|
|
// if (!head)
|
|
// {
|
|
// this->head = &node;
|
|
// this->tail = &node;
|
|
// this->length++;
|
|
// return;
|
|
// }
|
|
// if (typeid(head) != typeid(node))
|
|
// {
|
|
// lib::ArgVal::ThrowError(lib::ArgVal::ErrorMessage("node", "LinkedList.PushBack", node, typeid(head).name(), tail, true));
|
|
// }
|
|
// this->tail->SetPointer(&node, PointerType(NEXT));
|
|
// this->tail = &node;
|
|
// this->length++;
|
|
// return;
|
|
// }
|
|
// void Insert(T node, int index)
|
|
// {
|
|
// if (!head)
|
|
// {
|
|
// this->head = &node;
|
|
// this->tail = &node;
|
|
// this->length++;
|
|
// return;
|
|
// }
|
|
// if (typeid(head) != typeid(node))
|
|
// {
|
|
// lib::ArgVal::ThrowError(lib::ArgVal::ErrorMessage("node", "LinkedList.Insert", node, typeid(head).name(), tail, true));
|
|
// }
|
|
// if (index <= 0)
|
|
// {
|
|
// this->head->SetPointer(&node, PointerType(PREVIOUS));
|
|
// this->head = &node;
|
|
// this->length++;
|
|
// return;
|
|
// }
|
|
// if (index >= this->length)
|
|
// {
|
|
// this->tail->SetPointer(&node, PointerType(NEXT));
|
|
// this->tail = &node;
|
|
// this->length++;
|
|
// return;
|
|
// }
|
|
// LinkedListNode<T> nodeNext = *this->head;
|
|
// LinkedListNode<T> nodePrev;
|
|
// for (int n = 1; n < index; n++)
|
|
// {
|
|
// nodePrev = nodeNext;
|
|
// nodeNext = *nodePrev->GetPointer(PointerType(NEXT));
|
|
// }
|
|
// nodePrev.SetPointer(&node, PointerType(NEXT));
|
|
// nodeNext.SetPointer(&node, PointerType(PREVIOUS));
|
|
// this->length++;
|
|
// }
|
|
//private:
|
|
// LinkedListNode<T>* head;
|
|
// LinkedListNode<T>* tail;
|
|
// int length = 0;
|
|
//};
|
|
|
|
|
|
// NAMESPACE OBJECTS
|
|
namespace library123
|
|
{
|
|
struct enumPlusPlusItem
|
|
{
|
|
public:
|
|
enumPlusPlusItem(std::string name, int index);
|
|
std::string Name();
|
|
int Index();
|
|
std::string to_string();
|
|
private:
|
|
std::string name;
|
|
int index;
|
|
};
|
|
struct enumPlusPlus
|
|
{
|
|
public:
|
|
enumPlusPlus(std::vector<std::string> enumNames, int iStart = 0); // , std::string name = ""
|
|
std::string to_string();
|
|
int IStart();
|
|
int Size();
|
|
enumPlusPlusItem GetBy(int index, bool suppressErrors = false);
|
|
enumPlusPlusItem GetBy(std::string name, bool suppressErrors = false);
|
|
private:
|
|
std::string name;
|
|
std::vector<enumPlusPlusItem> enums;
|
|
int iStart;
|
|
};
|
|
enum eWoman
|
|
{
|
|
NIPPLE,
|
|
VAGINA,
|
|
BREAST
|
|
};
|
|
// template <typename T, typename U, typename V, typename W>
|
|
static class ArgVal // <T, U, V, W>
|
|
{
|
|
public:
|
|
template <typename W>
|
|
static bool IsString(const W& value);
|
|
/*
|
|
template <typename W>
|
|
struct IsAllowedType : std::false_type {};
|
|
template <>
|
|
struct IsAllowedType<int> : std::true_type {};
|
|
template <>
|
|
struct IsAllowedType<float> : std::true_type {};
|
|
template <>
|
|
struct IsAllowedType<double> : std::true_type {};
|
|
template <>
|
|
struct IsAllowedType<char> : std::true_type {};
|
|
template <>
|
|
struct IsAllowedType<bool> : std::true_type {};
|
|
template <>
|
|
struct IsAllowedType<void> : std::true_type {};
|
|
template <>
|
|
struct IsAllowedType<enumPlusPlus> : std::true_type {};
|
|
template <>
|
|
struct IsAllowedType<enumPlusPlusItem> : std::true_type {};
|
|
|
|
template <typename W>
|
|
typename std::enable_if<IsAllowedType<W>::value, void>::type
|
|
static std::string ToString(const W& arg);
|
|
*/
|
|
/*
|
|
template <typename W>
|
|
static std::string ToString(const std::vector<W>& arg);
|
|
*/
|
|
/*
|
|
template<Stringable S>
|
|
static std::string ToString(S s);
|
|
template<Stringable S>
|
|
static std::string ToString(std::vector<S> s);
|
|
*/
|
|
|
|
template <typename X>
|
|
struct IsPointer {
|
|
static constexpr bool value = false;
|
|
};
|
|
template <typename X>
|
|
struct IsPointer <X*> {
|
|
static constexpr bool value = true;
|
|
};
|
|
|
|
template <typename Y>
|
|
static Y ExtractValue(const Y& value);
|
|
|
|
template <typename Z>
|
|
static std::string ErrorHole(const std::vector<Z>& v);
|
|
template <typename Z1, typename Z2>
|
|
static std::string ErrorHole2(const std::vector<Z1>& v1, const std::vector<Z2>& v2);
|
|
|
|
|
|
template <typename T, typename U>
|
|
static std::string ErrorMessage(std::string varName, std::string funcName, T& var, std::string typeExpected, U& valueExpected, bool attrNotVar = false);
|
|
template <typename T, typename U>
|
|
static std::string ErrorMessage(std::string varName, std::string funcName, std::vector<T>& var, std::string typeExpected, std::vector<U>& valueExpected, bool attrNotVar = false);
|
|
template <typename T, typename U>
|
|
static std::string ErrorMessage(std::string varName, std::string funcName, const FastList<T>& var, std::string typeExpected, const FastList<U>& valueExpected, bool attrNotVar = false);
|
|
|
|
static void ThrowError(std::string errorMsg, bool raiseNotThrow = false);
|
|
static int main();
|
|
};
|
|
|
|
template <typename T>
|
|
struct HasMethodToString
|
|
{
|
|
template <typename U>
|
|
static std::true_type test(decltype(&U::to_string)*);
|
|
|
|
template <typename U>
|
|
static std::false_type test(...);
|
|
|
|
static constexpr bool value = decltype(test<T>(nullptr))::value;
|
|
};
|
|
|
|
class test_1
|
|
{
|
|
public:
|
|
int nudes;
|
|
std::string name;
|
|
test_1()
|
|
{
|
|
this->nudes = 1;
|
|
this->name = "Tierney";
|
|
}
|
|
std::string ToString() {
|
|
std::ostringstream oss;
|
|
oss << "test_1" << std::endl;
|
|
oss << "name: " << this->name << std::endl;
|
|
oss << "nudes: " << this->nudes << std::endl;
|
|
return oss.str();
|
|
}
|
|
};
|
|
|
|
class test_10
|
|
{
|
|
public:
|
|
std::list<int> aList1;
|
|
std::vector<typename std::list<int>::iterator> aIndex1;
|
|
test_10()
|
|
{
|
|
std::list<int> aList1 = std::list<int>();
|
|
std::vector<typename std::list<int>::iterator> aIndex1 = std::vector<typename std::list<int>::iterator>();
|
|
}
|
|
std::string ToString() {
|
|
std::ostringstream oss;
|
|
oss << "test_1" << std::endl;
|
|
// oss << "name: " << this->aList1 << std::endl;
|
|
// oss << "nudes: " << this->aIndex1 << std::endl;
|
|
return oss.str();
|
|
}
|
|
};
|
|
}
|
|
|
|
#endif DATA_TYPES_H |