#ifndef CONTAINER_HPP #define CONTAINER_HPP /* ************************************************************************** */ #include #include /* ************************************************************************** */ namespace lasd { /* ************************************************************************** */ class Container { private: protected: ulong size = 0; public: // Destructor virtual ~Container() = default; // Copy assignment Container& operator=(const Container&) = delete; // Copy assignment of abstract types should not be possible. // Move assignment Container& operator=(Container&&) noexcept = delete;; // Move assignment of abstract types should not be possible. // Comparison operators bool operator==(const Container&) const noexcept = delete; // Comparison of abstract types might not be possible. bool operator!=(const Container&&) const noexcept = delete; // Comparison of abstract types might not be possible. // Specific member functions virtual bool Empty() const noexcept { return (size == 0); } // (concrete function should not throw exceptions) virtual ulong Size() const noexcept { return size; } // (concrete function should not throw exceptions) virtual void Clear() = 0; }; template class LinearContainer : virtual public Container{ // Must extend Container private: protected: public: // Destructor virtual ~LinearContainer() = default; // Copy assignment LinearContainer& operator=(const LinearContainer&) = delete; // Copy assignment of abstract types should not be possible. // Move assignment LinearContainer& operator=(LinearContainer&&) noexcept = delete; // Move assignment of abstract types should not be possible. // Comparison operators bool operator==(const LinearContainer&) const noexcept = delete; // Comparison of abstract types might not be possible. bool operator!=(const LinearContainer&) const noexcept = delete; // Comparison of abstract types might not be possible. /* ************************************************************************ */ // Specific member functions virtual Data& Front() const = 0; // (concrete function must throw std::length_error when empty) virtual Data& Back() const = 0; // (concrete function must throw std::length_error when empty) virtual Data& operator[](const ulong) const = 0; // (concrete function must throw std::out_of_range when out of range) }; template class TestableContainer : virtual public Container{ // Must extend Container private: protected: public: // Destructor virtual ~TestableContainer() = default; // Copy assignment TestableContainer& operator=(const TestableContainer&) = delete; // Copy assignment of abstract types should not be possible. // Move assignment TestableContainer& operator=(TestableContainer&&) noexcept = delete; // Move assignment of abstract types should not be possible. // Comparison operators bool operator==(const TestableContainer&) const noexcept = delete; // Comparison of abstract types might not be possible. bool operator!=(const TestableContainer&) const noexcept = delete; // Comparison of abstract types might not be possible. /* ************************************************************************ */ // Specific member functions virtual bool Exists(const Data&) const noexcept = 0; // (concrete function should not throw exceptions) }; template class MappableContainer : virtual public Container { // Must extend Container private: protected: public: // Destructor virtual ~MappableContainer() = default; // Copy assignment MappableContainer& operator=(const MappableContainer&) = delete; // Copy assignment of abstract types should not be possible. // Move assignment MappableContainer& operator=(MappableContainer&&) noexcept = delete; // Move assignment of abstract types should not be possible. // Comparison operators bool operator==(const MappableContainer&) const noexcept = delete; // Comparison of abstract types might not be possible. bool operator!=(const MappableContainer&) const noexcept = delete; // Comparison of abstract types might not be possible. // Specific member functions typedef std::function MapFunctor; virtual void MapPreOrder(const MapFunctor, void*) = 0; virtual void MapPostOrder(const MapFunctor, void*) = 0; }; template class FoldableContainer : virtual public TestableContainer{ // Must extend TestableContainer private: protected: public: // Destructor virtual ~FoldableContainer() = default; // Copy assignment FoldableContainer& operator=(const FoldableContainer&) = delete; // Copy assignment of abstract types should not be possible. // Move assignment FoldableContainer& operator=(FoldableContainer&&) noexcept = delete; // Move assignment of abstract types should not be possible. // Comparison operators bool operator==(FoldableContainer&) const noexcept = delete; // Comparison of abstract types might not be possible. bool operator!=(FoldableContainer&) const noexcept = delete; // Comparison of abstract types might not be possible. // Specific member functions typedef std::function FoldFunctor; virtual void FoldPreOrder(const FoldFunctor, const void*, void*) const = 0; virtual void FoldPostOrder(const FoldFunctor, const void*, void*) const = 0; virtual bool Exists(const Data&) const noexcept override; // Override TestableContainer member }; /* ************************************************************************** */ template class InOrderMappableContainer : virtual public MappableContainer { // Must extend MappableContainer private: protected: public: // Destructor virtual ~InOrderMappableContainer() = default; /* ************************************************************************ */ // Copy assignment InOrderMappableContainer& operator=(const InOrderMappableContainer&) = delete; // Copy assignment of abstract types should not be possible. // Move assignment InOrderMappableContainer& operator=(InOrderMappableContainer&&) noexcept = delete; // Move assignment of abstract types should not be possible. /* ************************************************************************ */ // Comparison operators bool operator==(const InOrderMappableContainer&) const noexcept = delete; // Comparison of abstract types might not be possible. bool operator!=(const InOrderMappableContainer&) const noexcept = delete; // Comparison of abstract types might not be possible. /* ************************************************************************ */ // Specific member functions virtual void MapInOrder(const typename MappableContainer::MapFunctor, void*) = 0; }; /* ************************************************************************** */ template class InOrderFoldableContainer : public virtual FoldableContainer { // Must extend FoldableContainer private: protected: public: // Destructor virtual ~InOrderFoldableContainer() = default; /* ************************************************************************ */ // Copy assignment InOrderFoldableContainer& operator=(const InOrderFoldableContainer&) = delete; // Copy assignment of abstract types should not be possible. // Move assignment InOrderFoldableContainer& operator=(InOrderFoldableContainer&&) noexcept = delete; // Move assignment of abstract types should not be possible. /* ************************************************************************ */ // Comparison operators bool operator==(const InOrderFoldableContainer&) const noexcept = delete; // Comparison of abstract types might not be possible. bool operator!=(const InOrderFoldableContainer&) const noexcept = delete; // Comparison of abstract types might not be possible. /* ************************************************************************ */ // Specific member functions virtual void FoldInOrder(const typename FoldableContainer::FoldFunctor, const void*, void*) const = 0; }; /* ************************************************************************** */ template class BreadthMappableContainer : virtual public MappableContainer { // Must extend MappableContainer private: protected: public: // Destructor ~BreadthMappableContainer() = default; /* ************************************************************************ */ // Copy assignment BreadthMappableContainer& operator=(const BreadthMappableContainer&) = delete; // Copy assignment of abstract types should not be possible. // Move assignment BreadthMappableContainer& operator=(BreadthMappableContainer&&) noexcept = delete; // Move assignment of abstract types should not be possible. /* ************************************************************************ */ // Comparison operators bool operator==(const BreadthMappableContainer&) const noexcept = delete; // Comparison of abstract types might not be possible. bool operator!=(const BreadthMappableContainer&) const noexcept = delete; // Comparison of abstract types might not be possible. /* ************************************************************************ */ // Specific member functions virtual void MapBreadth(const typename MappableContainer::MapFunctor, void*) = 0; }; /* ************************************************************************** */ template class BreadthFoldableContainer : virtual public FoldableContainer { // Must extend FoldableContainer private: protected: public: // Destructor virtual ~BreadthFoldableContainer() = default; /* ************************************************************************ */ // Copy assignment BreadthFoldableContainer& operator=(const BreadthFoldableContainer&) = delete; // Copy assignment of abstract types should not be possible. // Move assignment BreadthFoldableContainer& operator=(BreadthFoldableContainer&&) noexcept = delete; // Move assignment of abstract types should not be possible. /* ************************************************************************ */ // Comparison operators bool operator==(const BreadthFoldableContainer&) const noexcept = delete; // Comparison of abstract types might not be possible. bool operator!=(const BreadthFoldableContainer&) const noexcept = delete; // Comparison of abstract types might not be possible. /* ************************************************************************ */ // Specific member functions using typename FoldableContainer::FoldFunctor; virtual void FoldBreadth(const FoldFunctor, const void*, void*) const = 0; }; /* ************************************************************************** */ } #include "container.cpp" #endif