Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //
- // Basic.h
- //
- #ifndef BASIC_GUARD
- #define BASIC_GUARD
- #include "../../Macro.h"
- namespace Algorithms
- {
- /**
- *\brief Swap values between two variables.
- *
- * \param First First variable.
- * \param Second Second variable.
- */
- template <typename Type>
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- void SwapByDeclaringTemporaryVariable(Type& First, Type& Second) CPPMACRO_NOEXCEPT
- {
- const Type Temporary = First;
- First = Second;
- Second = Temporary;
- }
- }
- #endif // BASIC_GUARD
- //
- // Array.h
- //
- #ifndef ARRAY_GUARD
- #define ARRAY_GUARD
- #include "../../Includes.h"
- #include "../../Macro.h"
- namespace Structures
- {
- /**
- * \brief Implementation of a dynamic array class.
- *
- * \tparam Type Type of data array has.
- */
- template<typename Type>
- class Array
- {
- /** @defgroup STL STL-like interface for a dynamic array class.
- * Used for compatibility with STL.
- * @{
- */
- using this_type = Array<Type>;
- using size_type = size_t;
- using value_type = Type;
- using reference = Type&;
- using const_reference = const Type&;
- using pointer = Type*;
- using const_pointer = const Type*;
- /** @defgroup Data group.
- * @{
- */
- /**
- * \brief Pointer to a dynamic array.
- */
- pointer mRaw = nullptr;
- /**
- * \brief Number of items.
- */
- size_type mSize = 0u;
- /**
- * @brief Constant used to pass in dynamic array constructor's argument.
- */
- static const size_type kDefaultAmountOfItems = 1u;
- public:
- /**
- *\brief Build a newly dynamically allocated array class with given amount of items provided in constructor's argument.
- * In case constructor called without argument constructs array class with default amount of items.
- *
- * \param Size Amount of items.
- */
- explicit
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- Array(const size_type Size = kDefaultAmountOfItems) : mSize {Size > 0u ? Size : throw (std::invalid_argument("Array(): invalid argument"))}
- {mRaw = new value_type[Size]();}
- /**
- *\brief Build a newly dynamically allocated array class with given amount of items and initialize items with provided value.
- *
- * \param Value Value used to initialize array's class items with.
- * \param Size Amount of items.
- */
- explicit
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- Array(const_reference Value, const size_type Size = kDefaultAmountOfItems)
- {
- if (Size > 0u)
- {
- Fill(Value);
- }
- }
- /**
- * @brief Build a newly dynamically allocated array class by using dynamically allocated (raw) array.
- *
- * @param Raw Pointer to a dynamically allocated (raw) array.
- * @param Size Amount of items.
- */
- explicit
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- Array(const_pointer Raw, const size_type Size) : Array(Size)
- {
- if (Size > 0u)
- {
- Copy(Raw, Size);
- }
- }
- /**
- * @brief Build a newly dynamically allocated array class by using another array class.
- *
- * @param Other Another dynamically allocated array class.
- */
- explicit
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- Array(const this_type& Other) : Array(Other.mSize)
- {
- if (!IsEquals(Other))
- {
- if (Other.mSize > 0u)
- {
- Copy(Other);
- }
- }
- }
- /**
- * @brief Build a newly dynamically allocated array class by using initialization list.
- *
- * @param InitializationList Initialization list to take values from.
- */
- #if defined (CPPMACRO_USE_INITIALIZATION_LIST)
- explicit
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- Array(const std::initializer_list<value_type> InitializationList)
- : Array(InitializationList.size() ? InitializationList.size()
- : throw (std::invalid_argument("Array(): array has no items!")))
- {
- decltype(mSize) InitializationListIterator = 0u;
- for (const_reference vPickItemFromList : InitializationList) {
- mRaw[InitializationListIterator++] =
- vPickItemFromList;
- }
- }
- #endif
- /**
- *\brief Destructor.
- */
- CPPMACRO_FORCEINLINE
- ~Array()
- { }
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- void Copy(const_pointer Raw, const size_type Size) CPPMACRO_NOEXCEPT
- {
- if (Raw != nullptr &&
- Size > 0u)
- {
- std::copy(Raw, Raw+Size, Raw);
- }
- }
- /**
- * @brief Copy items from another array class into this array class.
- *
- * @param Other Array class to take items from.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- void Copy(const this_type& Other) CPPMACRO_NOEXCEPT
- {
- if (mRaw != nullptr &&
- Other.mSize > 0u)
- {
- Copy(Other.mRaw, Other.mSize);
- mSize = Other.mSize;
- }
- }
- /**
- * @brief Append dynamically allocated array (raw array) at the end of this array class.
- *
- * @param Raw Pointer to a dynamically allocated array.
- * @param Size Amount of items.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- void Append(const_pointer Raw, const size_type Size) CPPMACRO_NOEXCEPT
- {
- if (Raw != nullptr &&
- !IsEmpty())
- {
- Resize(Size+Size);
- std::memcpy(reinterpret_cast<void*>(Raw+(mSize-Size)), Raw, sizeof(value_type)*Size);
- }
- }
- /**
- * @brief Append dynamically allocated array class at the end of this array class.
- *
- * @param Other Another dynamically allocated array class.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- void Append(const this_type& Other) CPPMACRO_NOEXCEPT
- {
- if (mRaw != nullptr &&
- Other.mRaw != nullptr &&
- !Other.IsEmpty())
- {
- Append(Other.mRaw, Other.mSize);
- }
- }
- /**
- * @brief Append dynamically allocated array class at the end of this array class.
- *
- * @param Other Another dynamically allocated array class.
- * @param Count Amount of items.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- void Append(const this_type& Other, const size_type Count) CPPMACRO_NOEXCEPT
- {
- if (mRaw != nullptr &&
- Other.mRaw != nullptr &&
- Count > 0u &&
- !Other.IsEmpty())
- {
- Append(Other.mRaw, Count);
- }
- }
- /**
- * @brief Assign data from another dynamically allocated array class to this dynamically allocated array class.
- *
- * @param Other Another dynamically allocated array class.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- this_type& Assign(const this_type& Other) CPPMACRO_NOEXCEPT
- {
- if (!IsEquals(Other))
- {
- if (mSize != Other.mSize)
- {
- Resize(mSize);
- }
- Copy(Other);
- }
- return (*this);
- }
- /**
- * @brief Get amount of items this array class contains.
- *
- * @returns Amount of items.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- size_type GetAmountOfItems() const CPPMACRO_NOEXCEPT
- {return (mSize);}
- /**
- * @brief Set new size for this dynamically allocated array class.
- *
- * @param NewSize New size.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- void Resize(const size_type NewSize) CPPMACRO_NOEXCEPT
- {
- pointer NewBuffer = new value_type[NewSize]();
- std::memcpy(reinterpret_cast<void*>(NewBuffer), mRaw, (mSize*sizeof(value_type)));
- mSize = NewSize;
- if (mRaw != nullptr)
- {
- delete[] mRaw;
- }
- mRaw = NewBuffer;
- }
- /**
- * @brief Set value at the provided index.
- *
- * @param Index Index at which set the value.
- * @param Value Value to set.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- void Set(const size_type Index, const_reference Value) CPPMACRO_NOEXCEPT
- {At(Index) = Value;}
- /**
- * @brief Addict new item to this dynamically allocated array class.
- *
- * @param Value Value to add.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- void Push(const_reference Value) CPPMACRO_NOEXCEPT
- {
- !IsEmpty() ? Resize(++mSize) : Resize(1);
- mRaw[(mSize-1u)] = Value;
- }
- /**
- * @brief Remove last item from this array class and return a reference to this item.
- *
- * @returns Reference to removed item.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- reference Pop() CPPMACRO_NOEXCEPT
- {
- value_type PopValue = mRaw[mSize-1u];
- Resize(--mSize);
- return (PopValue);
- }
- /**
- * @brief Check if given index lies within an allowed array's range,
- *
- * @param Index Index to check,
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- bool CheckIfIndexWithinAllowedRange(const size_type Index) const CPPMACRO_NOEXCEPT
- {
- if (Index < 0u || Index >= mSize)
- {
- return (false);
- }
- return (mRaw[Index]);
- }
- /**
- * @brief Return a reference at given index.
- *
- * @param Index Index to look up at,
- *
- * @returns Reference at given index,
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- reference At(const size_type Index) const CPPMACRO_NOEXCEPT
- {
- if (CheckIfIndexWithinAllowedRange(Index)) {
- return (mRaw[Index]);
- } else {
- return (mRaw[0u]);
- }
- }
- /**
- * @brief Get access to a first item in this array class.
- *
- * @returns Reference to a first item.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- reference GetFront() const CPPMACRO_NOEXCEPT
- {
- value_type Value = (mRaw[0u]);
- return (Value);
- }
- /**
- * @brief Get access to a last item in this array class.
- *
- * @returns Reference to a last item.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- reference GetBack() const CPPMACRO_NOEXCEPT
- {
- value_type Value = (mRaw[mSize-1u]);
- return (Value);
- }
- /**
- * @brief Get a raw representation of this array class.
- *
- * @returns Pointer to a data.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- const_pointer GetRaw() const CPPMACRO_NOEXCEPT
- {return (&mRaw[0u]);}
- /**
- * @brief Cast data to a given type.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- operator value_type&() CPPMACRO_NOEXCEPT
- {return (mRaw);}
- /**
- * @brief Fill the whole array class with given value.
- *
- * @param Value Value to fill items with.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- void Fill(const_reference Value) CPPMACRO_NOEXCEPT
- {
- if (mRaw != nullptr &&
- mSize > 0u)
- {
- std::fill(mRaw, mRaw+mSize, Value);
- }
- }
- /**
- * @brief Fill the array class with provided value starting from given index.
- *
- * @param From Index from which to start filling.
- * @param Value Value to fill items with.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- void Fill(const size_type From, const_reference Value) CPPMACRO_NOEXCEPT
- {
- if (mRaw != nullptr &&
- mSize > 0u)
- {
- std::fill(mRaw+From, mRaw+mSize, Value);
- }
- }
- /**
- * @brief Fill the array class with provided value starting from given index until given index.
- *
- * @param From Index from which to start filling.
- * @param To Index to fill until.
- * @param Value Value to fill with,
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- void Fill(const size_type From, const size_type To, const_reference Value) CPPMACRO_NOEXCEPT
- {
- if (mRaw != nullptr &&
- From > 0u &&
- To > 0u &&
- From < To &&
- mSize > 0u)
- {
- std::fill(mRaw +From, mRaw+To, Value);
- }
- }
- /**
- * @brief Check if given array class contains items.
- *
- * @returns True in case array class empty.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- bool IsEmpty() const CPPMACRO_NOEXCEPT
- {return (!mSize);}
- /**
- * @brief Check two given dynamically allocated array classes on equality.
- *
- * @param Other Another dynamically allocated array class to check.
- *
- * @returns True in case two array classes equals to each other.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- bool IsEquals(const this_type& Other) const CPPMACRO_NOEXCEPT
- {
- if (Other.mSize != mSize)
- {
- return (false);
- }
- if (std::equal(mRaw, mRaw+mSize, Other.mRaw, Other.mRaw+Other.mSize))
- {
- return (true);
- }
- return (false);
- }
- /**
- * @brief Get value at given index using C++'s access operator.
- *
- * @param Index Index to lookup value at.
- *
- * @returns Value at given index.
- */
- CPPMACRO_FORCEINLINE CPPMACRO_CONSTEXPR reference operator[](const size_type Index) {return (At(Index));}
- CPPMACRO_FORCEINLINE CPPMACRO_CONSTEXPR const value_type operator[](const size_type Index) const {return (At(Index));}
- /**
- * @brief Overloaded equality operator.
- *
- * @param Other Another dynamically allocated array class used to check.
- *
- * @returns True in case given array class equals to this array class.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- bool operator==(this_type& Other) const CPPMACRO_NOEXCEPT
- {return (IsEquals(Other));}
- /**
- * @brief Overloaded enequality operator.
- *
- * @param Other Another dynamically allocated array class used to check.
- *
- * @returns True in case given array class differs from this array class.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- bool operator!=(this_type& Other) const CPPMACRO_NOEXCEPT
- {return (!(operator==(Other)));}
- /**
- * @brief Overloaded comparison operators.
- *
- * @param Other Another dynamically allocated array class used to compare items with.
- *
- * @returns True if condition were met.
- */
- CPPMACRO_FORCEINLINE CPPMACRO_CONSTEXPR bool operator< (this_type& Other) const CPPMACRO_NOEXCEPT {return ((mSize < Other.mSize));}
- CPPMACRO_FORCEINLINE CPPMACRO_CONSTEXPR bool operator<=(this_type& Other) const CPPMACRO_NOEXCEPT {return ((mSize <= Other.mSize));}
- CPPMACRO_FORCEINLINE CPPMACRO_CONSTEXPR bool operator> (this_type& Other) const CPPMACRO_NOEXCEPT {return ((mSize > Other.mSize));}
- CPPMACRO_FORCEINLINE CPPMACRO_CONSTEXPR bool operator>=(this_type& Other) const CPPMACRO_NOEXCEPT {return ((mSize >= Other.mSize));}
- /**
- * @brief Build a string which represents content of this array class.
- *
- * @returns String with items.
- */
- CPPMACRO_FORCEINLINE std::string toString() const CPPMACRO_NOEXCEPT
- {
- std::stringstream Output;
- for (decltype(mSize) It = 0u; It < mSize; It++) {
- Output << "Index: " << It << " Value: " << mRaw[It] << " ";
- }
- return (Output.str());
- }
- /**
- * @brief Output content by using standart output device.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- void Print() const CPPMACRO_NOEXCEPT
- {
- if (!IsEmpty()) {
- std::cout << toString() << std::endl;
- }
- }
- };
- }
- #endif // ARRAY_GUARD
- //
- // SingleLinkedList.h
- //
- #ifndef SINGLELINKEDLIST_GUARD
- #define SINGLELINKEDLIST_GUARD
- #include "SingleLinkedListNode.h"
- /**
- * \brief Сache count.
- */
- #define CPPMACRO_CACHE_COUNT
- namespace Structures
- {
- /**
- * @brief Implementation of a linked list class (single linked list).
- *
- * @param Type Type of data list has.
- */
- template<typename Type>
- class SingleLinkedList
- {
- /** @defgroup STL STL-like interface for a single list class.
- * Used for compatibility with STL.
- * @{
- */
- using this_type = SingleLinkedList<Type>;
- using size_type = size_t;
- using value_type = Type;
- using reference = Type&;
- using const_reference = const Type&;
- using pointer = Type*;
- using const_pointer = const Type*;
- private:
- /**
- * @brief Constant used to pass in linked list constructor's argument.
- */
- static CPPMACRO_CONSTEXPR size_type kDefaultAmountOfItems = 1u;
- /** @defgroup Data group.
- *
- * @{
- */
- /**
- * @brief Node from which to start tracking items from.
- */
- SingleLinkedList<value_type>* mNodeHead;
- /**
- * @brief Use counter to track items count.
- */
- #if defined (CPPMACRO_CACHE_COUNT)
- size_type mCount;
- #endif
- public:
- /**
- * @brief Build empty linked list class, which doesn't contain any single item.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- SingleLinkedList() : mNodeHead {CPPMACRO_INVALID_NODE}
- #if defined (CPPMACRO_CACHE_COUNT)
- , mCount {0u}
- #endif
- { }
- /**
- * @brief Build linked list, which does contain single value provided by user.
- *
- * @param Value Value to put into.
- */
- explicit
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR SingleLinkedList(const_reference Value) : SingleLinkedList()
- {Append(Value);}
- /**
- * @brief Build linked list, which does contain set of values provided in argument.
- *
- * @param Value Value to put into.
- * @param Count Amount of items.
- */
- explicit
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- SingleLinkedList(const_reference Value, const size_type Count) : SingleLinkedList()
- {
- if (Count > 0u)
- {
- decltype (mCount) IdIterator = 0u;
- while (IdIterator < Count)
- {
- Append(Value);
- IdIterator++;
- }
- }
- }
- /**
- * @brief Build linked list, which does contains items from the raw array.
- *
- * @param Raw Dynamically allocated array.
- * @param Count Amount of items.
- */
- explicit
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- SingleLinkedList(const_pointer Raw, const size_type Count) : SingleLinkedList()
- {
- if (Raw != nullptr &&
- Count > 0u)
- {
- AppendRawArray(Raw, Count);
- }
- }
- /**
- * @brief Build linked list, which does contain values from the initialization list.
- *
- * @param InitializationList Initialization list.
- */
- explicit
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- SingleLinkedList(const std::initializer_list<value_type>& InitializationList) : SingleLinkedList()
- {
- if (InitializationList.size() != 0u)
- {
- AppendInitializerList(InitializationList);
- }
- }
- /**
- * @brief Build linked list, which does contain values from another list.
- *
- * @param Other Another linked list class.
- */
- explicit
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- SingleLinkedList(const this_type& Other) : SingleLinkedList()
- {
- if (Other.IsHasItems())
- {
- AppendList(Other);
- }
- }
- /**
- * @brief Destructor.
- */
- CPPMACRO_FORCEINLINE
- ~SingleLinkedList()
- {
- Clear();
- }
- /**
- * @brief Check if given linked list class contains items.
- *
- * @returns True in case list class has items.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- bool IsHasItems() const CPPMACRO_NOEXCEPT
- {return (mCount != 0u);}
- /**
- * @brief Check if this linked list class contains given item.
- *
- * @param Value Value to lookup for.
- *
- * @returns True if found.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- bool IsHasItem(const_reference Value) const CPPMACRO_NOEXCEPT
- {
- for (decltype(mCount) Iterator = 0u; Iterator < mCount; Iterator++)
- {
- if (GetValueById(Iterator) == Value)
- {
- return (true);
- }
- }
- return (false);
- }
- /**
- * @brief Check if this linked list class contains given dynamically allocated (raw) array.
- *
- * @param Raw Dynamically allocated (raw) array.
- * @param Count Amount of items.
- *
- * @returns True if found.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- bool IsHasRawArray(const_pointer Raw, const size_type Count) const CPPMACRO_NOEXCEPT
- {
- if (Raw != nullptr && Count > 0u)
- {
- for (decltype(mCount) Iterator = 0u; Iterator < Count; Iterator++)
- {
- const value_type Value = GetValueById(Iterator);
- if (IsHasItem(Value))
- {
- return (true);
- }
- }
- }
- return (false);
- }
- /**
- * @brief Check if this linked list class contains given initialization list.
- *
- * @param InitializerList Initialization list.
- *
- * @returns True if found.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- bool IsHasInitializerList(const std::initializer_list<value_type> InitializerList) const CPPMACRO_NOEXCEPT
- {
- if (InitializerList.size())
- {
- for (const_reference Value : InitializerList)
- {
- decltype(mNodeHead) NodeIterator = Create(Value);
- if (NodeIterator != CPPMACRO_INVALID_NODE)
- {
- return (NodeIterator->GetData() == Value);
- }
- }
- }
- return (false);
- }
- /**
- * @brief Check if this linked list class contains given list.
- *
- * @param Other Another linked list class.
- *
- * @returns True if found.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- bool IsHasList(const SingleLinkedList<value_type>& Other) const CPPMACRO_NOEXCEPT
- {
- for (decltype(mCount) Iterator = 0u; Iterator < Other.mCount; Iterator++)
- {
- if (GetValueById(Iterator) != Other.GetValueById(Iterator))
- {
- return (false);
- }
- }
- return (true);
- }
- /**
- * @brief Check if this linked list class and it's content equals given list.
- *
- * @param Other Another linked list class.
- *
- * @returns True if equals.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- bool IsEquals(const this_type& Other) const CPPMACRO_NOEXCEPT
- {
- if (Other.mCount != mCount)
- {
- return (false);
- }
- if (Other != *this)
- {
- for (decltype(mCount) Iterator = 0u; Iterator < mCount; Iterator++)
- {
- if (GetValueById(Iterator) != Other.GetValueById(Iterator))
- {
- return (false);
- }
- }
- }
- return (true);
- }
- /**
- * @brief Get value at the beggining of a linked list class.
- *
- * @returns Value of first item.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- value_type GetFront() CPPMACRO_NOEXCEPT
- {return (mNodeHead->GetData());}
- /**
- * @brief Get value at the end of a linked list class.
- *
- * @returns Value of last item.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- value_type GetBack() CPPMACRO_NOEXCEPT
- {return (GetValueById(mCount));}
- /**
- * @brief Get the value being stored at given index in a linked list class.
- *
- * @param Id Index at which to look for value.
- *
- * @returns Value.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- const_reference GetValueById(const size_type Id) const CPPMACRO_NOEXCEPT
- {
- decltype(mNodeHead) NodeIterator = mNodeHead;
- decltype(mCount) IdIterator = 0u;
- while (IdIterator < Id)
- {
- NodeIterator = NodeIterator->GetNext();
- IdIterator++;
- }
- return (NodeIterator->GetData());
- }
- /**
- * @brief Get the index of the first occurrence for a given value.
- *
- * @param Value Value to look up for in a linked list class.
- *
- * @returns Index.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- size_type GetIdByValue(const_reference Value) const CPPMACRO_NOEXCEPT
- {
- decltype(mNodeHead) NodeIterator = mNodeHead;
- decltype(mCount) IdIterator = 0u;
- while (NodeIterator != CPPMACRO_INVALID_NODE)
- {
- if (NodeIterator->GetData() == Value)
- {
- return (IdIterator);
- }
- NodeIterator = NodeIterator->GetNext();
- IdIterator++;
- }
- return (0u);
- }
- /**
- * @brief Get the index of the last occurrence for a given value.
- *
- * @param Value Value to look up for in a linked list class.
- *
- * @returns Index.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- size_type GetLastIdByValue(const_reference Value) const CPPMACRO_NOEXCEPT
- {
- decltype(mNodeHead) NodeIterator = mNodeHead;
- decltype(mCount) IdIterator = 0u,
- IdCounter = 0u;
- while (NodeIterator != CPPMACRO_INVALID_NODE)
- {
- if (NodeIterator->GetData() == Value)
- {
- IdCounter = IdIterator;
- }
- NodeIterator = NodeIterator->GetNext();
- IdIterator++;
- }
- return (IdCounter);
- }
- /**
- * @brief Get amount of items in this linked list class.
- *
- * @returns Size of a list.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- size_type GetSize() const CPPMACRO_NOEXCEPT
- {
- decltype(mNodeHead) NodeIterator = mNodeHead;
- decltype(mCount) ItemCounter = 0u;
- while (NodeIterator != CPPMACRO_INVALID_NODE)
- {
- NodeIterator = NodeIterator->GetNext();
- ItemCounter++;
- }
- return (ItemCounter);
- }
- /**
- * @brief Clear the list.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- void Clear() CPPMACRO_NOEXCEPT
- {
- #if defined (CPPMACRO_CACHE_COUNT)
- mCount = 0u;
- #endif
- }
- /**
- * @brief Create a new node instance with given value.
- *
- * @param[in] Value Value in node.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- SingleLinkedListNode<value_type>*
- Create(const_reference Value) const CPPMACRO_NOEXCEPT
- {
- const decltype(mNodeHead) NewNode = new (std::nothrow) SingleLinkedListNode<value_type>(Value);
- if (NewNode != CPPMACRO_INVALID_NODE)
- {
- return (NewNode);
- }
- return (CPPMACRO_INVALID_NODE);
- }
- /**
- * @brief Set a new size of a linked list class.
- *
- * @param NewCount New size to set.
- * @param Value Value to set in case willing size of a linked list is more then old one.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- void Resize(const size_type NewCount, const_reference Value = 0u) CPPMACRO_NOEXCEPT
- {
- if (NewCount != GetSize())
- {
- if (NewCount > GetSize())
- {
- while (GetSize() != NewCount)
- {Append(Value);}
- }
- if (NewCount < GetSize())
- {
- while (GetSize() != NewCount)
- {DeleteBack();}
- }
- }
- }
- /**
- * @brief Replaces the item at the specified index in this linked list class with a new one.
- *
- * @param Id Index at which to replace.
- * @param Value Value.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- void Set(const size_type Id, const_reference Value) CPPMACRO_NOEXCEPT
- {
- decltype (mNodeHead) NodeIterator = mNodeHead;
- decltype (mCount) IdIterator = 0u;
- while (NodeIterator != CPPMACRO_INVALID_NODE)
- {
- if (IdIterator == Id)
- {
- decltype(mNodeHead) NewNode = Create(Value);
- if (NewNode != CPPMACRO_INVALID_NODE)
- {
- NodeIterator->SetData(Value);
- }
- }
- IdIterator++;
- NodeIterator = NodeIterator->GetNext();
- }
- }
- /**
- * @brief Insert the item at the specified index in this linked list class.
- *
- * @param Id Index to insert in.
- * @param Value Value.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- void Insert(const size_type Id, const_reference Value) CPPMACRO_NOEXCEPT
- {
- if (!IsHasItems())
- {
- Append(Value);
- return;
- }
- const decltype (mNodeHead) NewNode = Create(Value);
- if (Id == 0u)
- {
- NewNode->SetNext(mNodeHead);
- mNodeHead = NewNode;
- #if defined (CPPMACRO_CACHE_COUNT)
- mCount++;
- #endif
- } else if (Id == mCount)
- { Append(Value);
- } else {
- decltype(mNodeHead) NodeIterator = mNodeHead, NodePrevious = CPPMACRO_INVALID_NODE;
- if (NodeIterator != CPPMACRO_INVALID_NODE)
- {
- decltype(mCount) IdIterator = 1u;
- while (IdIterator < Id)
- {
- NodePrevious = NodeIterator;
- NodeIterator = NodeIterator->GetNext();
- IdIterator++;
- }
- NewNode->SetNext(NodeIterator);
- NodePrevious->SetNext(NewNode);
- }
- }
- }
- /**
- * @brief Insert given raw array into given position of the linked list class.
- *
- * @param Id Id after which to insert into a raw array.
- * @param Raw Dynamically allocated (raw) array.
- * @param Count Amount of items.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- void InsertRawArray(const size_type Id, const_pointer Raw, const size_type Count) CPPMACRO_NOEXCEPT
- {
- if (Id > 0u && Raw != nullptr && Count > 0u)
- {
- decltype(mCount) IdIterator = Id;
- while (IdIterator < Id)
- {
- const value_type Value = GetValueById(IdIterator);
- Insert(IdIterator, Value);
- IdIterator++;
- }
- }
- }
- /**
- * @brief Insert given initialization list into given position of the linked list class.
- *
- * @param Id Id after which to insert initialization list.
- * @param InitializerList Initialization list.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- void InsertInitializerList(const size_type Id, const std::initializer_list<value_type> InitializerList) CPPMACRO_NOEXCEPT
- {
- if (InitializerList.size())
- {
- decltype(mCount) IdIterator = Id;
- for (const_reference Value : InitializerList)
- {
- Insert(IdIterator, Value);
- IdIterator++;
- }
- }
- }
- /**
- * @brief Insert given linked list into given position of the linked list class.
- *
- * @param Id Id after which to insert linked list.
- * @param Other Linked list class.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- void InsertLinkedList(const size_type Id, const this_type& Other) const CPPMACRO_NOEXCEPT
- {
- if (Other.IsHasItems())
- {
- decltype(mCount) IdIterator = Id;
- while (IdIterator < Id)
- {
- Insert(Id, GetValueById(IdIterator));
- IdIterator++;
- }
- }
- }
- /**
- * @brief Append a single value at the end of a linked list class.
- *
- * @param Value Value used to append.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- void Append(const_reference Value) CPPMACRO_NOEXCEPT
- {
- const decltype(mNodeHead) NewNode = Create(Value);
- if (NewNode != CPPMACRO_INVALID_NODE)
- {
- if (!IsHasItems())
- {
- mNodeHead = NewNode;
- #if defined (CPPMACRO_CACHE_COUNT)
- mCount = 1u;
- #endif
- } else {
- decltype(mNodeHead) NodeIterator = mNodeHead;
- while (NodeIterator->GetNext() != CPPMACRO_INVALID_NODE)
- {
- NodeIterator = NodeIterator->GetNext();
- }
- NodeIterator->SetNext(NewNode);
- mCount++;
- }
- }
- }
- /**
- * @brief Append a dynamically allocated array (raw array) at the end of a linked list class.
- *
- * @param Raw Dynamically allocated array (raw array).
- * @param Count Amount of items.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- void AppendRawArray(const_pointer Raw, const size_type Count) CPPMACRO_NOEXCEPT
- {
- if (Raw != nullptr && Count > 0u)
- {
- for (decltype(mCount) Iterator = 0u; Iterator < Count; Iterator++)
- {
- Append(Raw[Iterator]);
- }
- }
- }
- /**
- * @brief Append a list of values at the end of a linked list class.
- *
- * @param InitializerList Initialization list.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- void AppendInitializerList(const std::initializer_list<value_type>& InitializerList) CPPMACRO_NOEXCEPT
- {
- if (InitializerList.size() != 0u)
- {
- for (const_reference Value : InitializerList)
- {
- Append(Value);
- }
- }
- }
- /**
- * @brief Append a linked list class at the end of a linked list class.
- *
- * @param Other Another linked list class.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- void AppendList(const this_type& Other) CPPMACRO_NOEXCEPT
- {
- if (Other.IsHasItems())
- {
- decltype(mNodeHead) NodeIterator = Other.mNodeHead;
- while (NodeIterator != CPPMACRO_INVALID_NODE)
- {
- Append(NodeIterator->GetData());
- NodeIterator = NodeIterator->GetNext();
- }
- }
- }
- /**
- * @brief Insert value at the beggining of the linked list class,
- *
- * @param Value Value to push at the beggining.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- void InsertFront(const_reference Value) CPPMACRO_NOEXCEPT
- {Insert(0u, Value);}
- /**
- * @brief Insert value at the end of the linked list class,
- *
- * @param Value Value to push at the end.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- void InsertBack(const_reference Value) CPPMACRO_NOEXCEPT
- {Append(Value);}
- /**
- * @brief Delete item with given id from linked list class.
- *
- * @param Id Index to delete,
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- void DeleteById(const size_type Id) CPPMACRO_NOEXCEPT
- {
- if (!IsHasItems() &&
- Id > mCount)
- {
- return;
- }
- decltype(mNodeHead) NodeIterator = mNodeHead;
- if (NodeIterator != CPPMACRO_INVALID_NODE)
- {
- decltype(mCount) IdIterator = Id;
- while (IdIterator < Id)
- {
- NodeIterator = NodeIterator->GetNext();
- if (NodeIterator != CPPMACRO_INVALID_NODE)
- {
- IdIterator++;
- }
- }
- NodeIterator->SetNext(NodeIterator->GetNext()->GetNext());
- }
- }
- /**
- * @brief Delete item with given value from linked list class.
- *
- * @param Value Value used to delete.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- void DeleteByValue(const_reference Value) CPPMACRO_NOEXCEPT
- {
- if (IsHasItems())
- {
- const CPPMACRO_CONSTEXPR size_type Id = GetIdByValue(Value);
- if (Id > 0u)
- {
- DeleteById(Id);
- }
- }
- }
- /**
- * @brief Delete all occurances with given values from linked list class.
- *
- * @param Value Values used to delete.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- void DeleteByValueAllOccurances(const_reference Value) CPPMACRO_NOEXCEPT
- {
- if (IsHasItems())
- {
- decltype(mNodeHead) NodeIterator = mNodeHead;
- decltype(mCount) IdIterator = 0u;
- while (IdIterator < mCount)
- {
- NodeIterator = NodeIterator->GetNext();
- if (NodeIterator->GetData() == Value)
- {
- DeleteById(IdIterator);
- }
- IdIterator++;
- }
- }
- }
- /**
- * @brief Delete value located in from of a linked list class.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- void DeleteFront() CPPMACRO_NOEXCEPT
- {
- if (IsHasItems())
- {
- DeleteById(0u);
- }
- }
- /**
- * @brief Delete value located at back of a linked list class.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- void DeleteBack() CPPMACRO_NOEXCEPT
- {
- if (IsHasItems())
- {
- DeleteById(GetSize());
- }
- }
- /**
- * @brief Delete first value from a linked list and return deleted value.
- *
- * @return Deleted value.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- value_type PopFront() CPPMACRO_NOEXCEPT
- {
- const CPPMACRO_CONSTEXPR value_type Value = GetFront();
- DeleteById(0u);
- return (Value);
- }
- /**
- * @brief Delete last value from a linked list and return deleted value.
- *
- * @return Deleted value.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- value_type PopBack() CPPMACRO_NOEXCEPT
- {
- const CPPMACRO_CONSTEXPR value_type Value = GetBack();
- DeleteById(mCount);
- return (Value);
- }
- /**
- * @brief Create a new instance of a linked list class by taking initial index and last index of this class.
- *
- * @param From Index used to start building linked list class.
- * @param To Index to finish linked list.
- *
- * @return New list.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- this_type Create(const size_type From, const size_type To) const CPPMACRO_NOEXCEPT
- {
- if (From > 0u && To > From && IsHasItems())
- {
- const CPPMACRO_CONSTEXPR this_type CreateNewListClass;
- decltype(mCount) IdIterator = From;
- while (IdIterator < To)
- {
- const CPPMACRO_CONSTEXPR value_type Value = GetValueById(IdIterator);
- CreateNewListClass.Insert(IdIterator, Value);
- IdIterator++;
- }
- return (CreateNewListClass);
- }
- return (*this);
- }
- /**
- * @brief Use C++'s access operator to get a value at given index.
- *
- * @param Index Index to lookup value at.
- *
- * @returns Value at given index.
- */
- CPPMACRO_FORCEINLINE value_type operator[](const size_type Index) {return (GetValueById(Index));}
- CPPMACRO_FORCEINLINE const value_type operator[](const size_type Index) const {return (GetValueById(Index));}
- /**
- * @brief Overloaded comparison operators.
- *
- * @param Other Another linked list class used to compare items with.
- *
- * @returns True if condition were met.
- */
- CPPMACRO_FORCEINLINE bool operator< (this_type& Other) const CPPMACRO_NOEXCEPT {return ((mCount < Other.mCount));}
- CPPMACRO_FORCEINLINE bool operator<=(this_type& Other) const CPPMACRO_NOEXCEPT {return ((mCount <= Other.mCount));}
- CPPMACRO_FORCEINLINE bool operator> (this_type& Other) const CPPMACRO_NOEXCEPT {return ((mCount > Other.mCount));}
- CPPMACRO_FORCEINLINE bool operator>=(this_type& Other) const CPPMACRO_NOEXCEPT {return ((mCount >= Other.mCount));}
- /**
- * @brief Overloaded equality operator.
- *
- * @param Other Another linked list class used to check.
- *
- * @returns True on equality.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- bool operator==(this_type& Other) const CPPMACRO_NOEXCEPT
- {
- if (IsEquals(Other))
- {
- return (true);
- }
- return (false);
- }
- /**
- * @brief Overloaded enequality operator.
- *
- * @param Other Another linked list class used to check.
- *
- * @returns True on enequality.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- bool operator!=(this_type& Other) const CPPMACRO_NOEXCEPT
- {
- if (!(operator==(Other)))
- {
- return (true);
- }
- return (false);
- }
- /**
- * @brief Overloaded assignment operator.
- *
- * @param Other Instance of a linked list class to take items from.
- *
- * @returns Linked list class.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- this_type& operator=(const this_type& Other) const CPPMACRO_NOEXCEPT
- {
- if (std::addressof(Other) != this &&
- Other.IsHasItems())
- {
- const CPPMACRO_CONSTEXPR this_type LinkedList;
- LinkedList.Clear();
- LinkedList.InsertLinkedList(0u, Other);
- return (LinkedList);
- }
- return (*this);
- }
- /**
- * @brief Overloaded assignment operator.
- *
- * @param Other Instance of a linked list class to take items from.
- *
- * @returns Linked list class.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- this_type operator+=(const this_type& Other) const CPPMACRO_NOEXCEPT
- {
- const CPPMACRO_CONSTEXPR this_type LinkedList;
- LinkedList.operator=(this);
- LinkedList.AppendList(Other);
- return (*this);
- }
- /**
- * @brief Build a string which represents content of this forward list class.
- *
- * @returns String with items.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- std::string toString() const CPPMACRO_NOEXCEPT
- {
- decltype(mNodeHead) NodeIterator = mNodeHead;
- std::stringstream StreamContent;
- while (NodeIterator != CPPMACRO_INVALID_NODE)
- {
- StreamContent << NodeIterator->GetData() << " ";
- NodeIterator = NodeIterator->GetNext();
- }
- StreamContent << std::endl;
- return (StreamContent.str());
- }
- /**
- * @brief Output list content by using standart output device.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- void Print() const CPPMACRO_NOEXCEPT
- {
- if (!IsHasItems()) {
- std::cout << "SingleLinkedList: linked list class has no items!" << std::endl;
- return;
- }
- std::cout << toString() << std::endl;
- }
- };
- }
- }
- #endif // SINGLELINKEDLIST_GUARD
- //
- // SingleLinkedListNode.h
- //
- #ifndef SINGLELINKEDLISTNODE_GUARD
- #define SINGLELINKEDLISTNODE_GUARD
- #include "../../../Includes.h"
- #include "../../../Macro.h"
- /**
- * \brief Invalid node.
- */
- #define CPPMACRO_INVALID_NODE nullptr
- namespace Structures
- {
- /**
- * @brief Node class.
- *
- * @param Value Value this node instance has.
- */
- template<typename Type>
- class SingleLinkedListNode
- {
- /** @defgroup STL STL-like interface for a node class.
- * Used for compatibility with STL.
- * @{
- */
- using this_type = SingleLinkedListNode<Type>;
- using value_type = Type;
- using reference = Type&;
- using const_reference = const Type&;
- using pointer = Type*;
- using const_pointer = const Type*;
- /** @defgroup Data group.
- * @{
- */
- /**
- * @brief Next node followed by this node instance.
- */
- this_type* mNext;
- /**
- * @brief Value this node instance has.
- */
- value_type mData;
- public:
- /**
- * @brief Default constructor.
- *
- * Create a new node with value initialized to zero.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- SingleLinkedListNode() : mNext {CPPMACRO_INVALID_NODE}, mData {0u}
- { }
- /**
- * @brief User-defined constructor.
- *
- * Create a new node with value provided in constructor's argument.
- *
- * @param Value Value this node instance has.
- */
- explicit
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- SingleLinkedListNode(const_reference Value) : mNext {CPPMACRO_INVALID_NODE}, mData {Value}
- { }
- /**
- * @brief User-defined constructor.
- *
- * @param Value Value this node instance has.
- * @param Next Next node instance followed by this node instance.
- */
- explicit
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- SingleLinkedListNode(const_reference Value, this_type* Next) : mNext {Next}, mData {Value}
- { }
- /**
- * @brief Get value in this node instance.
- *
- * @returns Value.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- reference GetData() CPPMACRO_NOEXCEPT
- {return (mData);}
- /**
- * @brief Set data this node instance going to contain.
- *
- * @param Value Value.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- void SetData(const_reference Value) CPPMACRO_NOEXCEPT
- {mData = Value;}
- /**
- * @brief Get next node followed by this node instance.
- *
- * @returns Next node.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- this_type* GetNext() const CPPMACRO_NOEXCEPT
- {return (mNext);}
- /**
- * @brief Set next node followed by this node instance.
- *
- * @param Next Next node.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- void SetNext(this_type* Next) CPPMACRO_NOEXCEPT
- {mNext = Next;}
- };
- }
- }
- }
- #endif // SINGLELINKEDLISTNODE_GUARD
- //
- // String.h
- //
- #ifndef STRING_GUARD
- #define STRING_GUARD
- #include "../../Includes.h"
- #include "../../Macro.h"
- namespace Structures
- {
- /**
- * \brief Class (wrapper) for a raw C string.
- */
- class String
- {
- /**
- * \brief
- */
- using USING_RAW_C_STRING = char*;
- /**
- * \brief
- */
- using USING_RAW_CONSTANT_C_STRING = const USING_RAW_C_STRING;
- /**
- * \brief
- */
- using USING_SIZE_TYPE = size_t;
- /**
- * \brief Pointer to a C string.
- */
- char* mRaw = nullptr;
- public:
- /**
- * \brief Constructor for a raw C string.
- *
- * \param Raw mRaw C string.
- */
- explicit
- CPPMACRO_FORCEINLINE
- String(char* Raw)
- {mRaw = Raw;}
- /**
- * \brief Get (getter for) a raw C string.
- *
- * \return Pointer to a raw C string.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- USING_RAW_C_STRING Raw() const CPPMACRO_NOEXCEPT
- {return (mRaw);}
- /**
- * \brief Get string length.
- * \return String length.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- size_t GetLength() const CPPMACRO_NOEXCEPT
- {
- size_t Count = 0u;
- while (mRaw[Count] != '\0') {
- Count++;
- }
- return (Count);
- }
- /**
- * \brief Get character used to store at given index.
- *
- * \param Index Index to lookup character at.
- * \return Character at given index.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- char GetCharacterAtGivenIndex(const size_t Index) const CPPMACRO_NOEXCEPT
- {
- if (Index <= 0u) {
- return ('\0');
- }
- return (mRaw[Index]);
- }
- /**
- * \brief Reverse a string by using STL routines.
- */
- CPPMACRO_FORCEINLINE
- CPPMACRO_CONSTEXPR
- void ReverseUsingSTLRoutines() const CPPMACRO_NOEXCEPT
- {
- std::reverse(mRaw, mRaw+GetLength());
- }
- };
- }
- #endif // STRING_GUARD
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement