不定类型动态数组

不定类型的动态数组,依赖多态以及 template 实现

#include <typeinfo>
#include <assert.h>
#include <algorithm>
#include <iostream>
#include <string>

class List
{
public:
    using size_t = unsigned long long int;
    using pos_t = long long int;
    class Any
    {
    private:
        class Object
        {
        public:
            virtual ~Object() {}
            virtual const std::type_info &type() const = 0;
            virtual Object *clone() const = 0;
        };
        template <typename T>
        class Element : public Object
        {
        public:
            Element(const T &value);

        public:
            virtual const std::type_info &type() const;
            virtual Object *clone() const;
            T &data();

        private:
            T _data;
        };

    private:
        Object *content = nullptr;

    public:
        Any();

        template <typename T>
        Any(const T &value);

        Any(const Any &other);

        ~Any();

        void erase();

        bool empty() const;

        void move_to(Any &destination);

        template <typename T>
        T &cast();

        template <typename T>
        operator T();

        void swap(Any &other);

        const std::type_info &type() const;

        Any &operator=(const Any &other);

        template <typename T>
        Any &operator=(const T &value);

        Any *clone() const;
    };

    class Iterator
    {
    public:
        Iterator(Any *pos);
        Any operator*() const;
        bool operator!=(const Iterator &other) const;
        bool operator==(const Iterator &other) const;
        const Iterator &operator++();
        const Iterator &operator--();
        const Iterator &operator++(int);
        const Iterator &operator--(int);
        Iterator &operator=(const Iterator &other);

    private:
        Any *_pos;
    };

private:
    size_t _length, _capacity;
    Any *list = nullptr;

public:
    List(size_t len = 0);

    List(const List &other);

    List(const List *other);

    ~List();

    size_t length() const;

    size_t capacity() const;

    void resize(size_t len);

    template <typename T>
    void add(const T &value);

    void add(const char *value);

    void pop();

    void pop(size_t num);

    void clear();

    void swap(List &other);

    Any &operator[](pos_t index);

    Any &at(size_t index);

    List reversed() const;

    List *clone() const;

    List &operator=(const List &other);

    List &operator+(const List &other) const;

    List &operator+=(const List &other);

    List operator()(pos_t st, pos_t ed) const;

    Any operator()(pos_t index) const;

    Iterator begin();

    Iterator end();
};

List::Iterator::Iterator(Any *pos) : _pos(pos) {}

typename List::Any List::Iterator::operator*() const { return *_pos; }

bool List::Iterator::operator!=(const List::Iterator &other) const { return _pos != other._pos; }

bool List::Iterator::operator==(const List::Iterator &other) const { return _pos == other._pos; }

const typename List::Iterator &List::Iterator::operator++()
{
    ++_pos;
    return *this;
}
const typename List::Iterator &List::Iterator::operator++(int flag)
{
    Iterator *ret = new Iterator(_pos);
    ++_pos;
    return *ret;
}
const typename List::Iterator &List::Iterator::operator--()
{
    Iterator *ret = new Iterator(_pos);
    --_pos;
    return *ret;
}
const typename List::Iterator &List::Iterator::operator--(int flat)
{
    --_pos;
    return *this;
}

typename List::Iterator &List::Iterator::operator=(const typename List::Iterator &other)
{
    _pos = other._pos;
    return *this;
}

template <typename T>
List::Any::Element<T>::Element(const T &value) : _data(value) {}

template <typename T>
const std::type_info &List::Any::Element<T>::type() const
{
    return typeid(T);
}

template <typename T>
typename List::Any::Object *List::Any::Element<T>::clone() const
{
    return new Element(_data);
}

template <typename T>
T &List::Any::Element<T>::data()
{
    return _data;
}

List::Any::Any() : content(nullptr) {}

template <typename T>
List::Any::Any(const T &value) : content(new Element<T>(value)) {}

List::Any::Any(const Any &other) : content(other.content == nullptr ? nullptr : other.content->clone()) {}

List::Any::~Any() { erase(); }

bool List::Any::empty() const
{
    return content == nullptr;
}

void List::Any::erase()
{
    if (!empty())
    {
        delete content;
        content = nullptr;
    }
}

void List::Any::move_to(Any &destination)
{
    destination.erase();
    if (!empty())
        destination.content = content;
    content = nullptr;
}

template <typename T>
T &List::Any::cast()
{
    if (empty())
    {
        throw "Cast nullptr!";
    }
    return dynamic_cast<typename List::Any::Element<T> *>(content)->data();
}

template <typename T>
List::Any::operator T()
{
    return cast<T>();
}

void List::Any::swap(Any &other)
{
    std::swap(content, other.content);
}

const std::type_info &List::Any::type() const
{
    return (content == nullptr) ? typeid(void) : content->type();
}

typename List::Any &List::Any::operator=(const List::Any &other)
{
    if (content == other.content)
    {
        return *this;
    }
    erase();
    content = other.content == nullptr ? nullptr : other.content->clone();
    return *this;
}

template <typename T>
typename List::Any &List::Any::operator=(const T &value)
{
    erase();
    content = new Element<T>(value);
    return *this;
}

typename List::Any *List::Any::clone() const
{
    return new Any(*this);
}

List::List(List::size_t len)
{
    _length = 0;
    _capacity = 0;
    resize(len);
}

List::List(const List &other) : List(&other) {}

List::List(const List *other)
{
    if (other == nullptr)
    {
        clear();
    }
    else
    {
        if (list != nullptr)
        {
            delete[] list;
        }
        _length = other->_length;
        _capacity = other->_capacity;
        list = other->clone()->list;
    }
}

List::~List()
{
    delete[] list;
}

List::size_t List::length() const
{
    return _length;
}

List::size_t List::capacity() const
{
    return _capacity;
}

void List::resize(size_t new_length)
{
    for (size_t i = new_length + 1; i < _capacity; ++i)
        list[i].erase();
    size_t new_capacity = new_length << 1;
    if (new_capacity == 0)
        new_capacity = 2;
    Any *new_list = new Any[new_capacity];
    {
        size_t lim = _length < new_length ? _length : new_length;
        for (size_t i = 0; i < lim; i++)
        {
            list[i].move_to(new_list[i]);
        }
    }
    _length = new_length;
    _capacity = new_capacity;
    list = new_list;
}

template <typename T>
void List::add(const T &value)
{
    if (_length == _capacity)
    {
        resize(_length);
    }
    list[_length++] = Any(value);
}

void List::add(const char *value)
{
    add(std::string(value));
}

void List::pop()
{
    if (_length == 0)
        throw "Empty pop";
    list[--_length].erase();
    if (_length < (_capacity >> 2))
        resize(_length);
}

void List::pop(List::size_t num)
{
    for (size_t i = 0; i < num; ++i)
    {
        pop();
    }
}

void List::clear()
{
    resize(0);
}

void List::swap(List &other)
{
    std::swap(_length, other._length);
    std::swap(_capacity, other._capacity);
    std::swap(list, other.list);
}

typename List::Any &List::operator[](List::pos_t index)
{
    if (index < 0)
    {
        index += _length;
    }
    if (index < 0 || index >= (pos_t)_length)
    {
        throw "Index Out Of Bounds Exception";
    }
    return list[index];
}

List *List::clone() const
{
    List *ret = new List();
    ret->_length = _length;
    ret->_capacity = _capacity;
    ret->list = new Any[_capacity];
    for (size_t i = 0; i < _length; ++i)
    {
        ret->list[i] = *list[i].clone();
    }
    return ret;
}

List &List::operator+(const List &other) const
{
    List *ret = new List(_length + other._length);
    for (size_t i = 0; i < _length; i++)
    {
        ret->list[i] = *list[i].clone();
    }
    for (size_t i = 0; i < other._length; i++)
    {
        ret->list[i + _length] = *other.list[i].clone();
    }
    return *ret;
}

List &List::operator+=(const List &other)
{
    size_t old_length = _length;
    resize(_length + other._length);
    for (size_t i = old_length; i < _length; i++)
    {
        list[i] = *other.list[i].clone();
    }
    return *this;
}

List &List::operator=(const List &other)
{
    List *ptr = other.clone();
    _length = ptr->_length;
    _capacity = ptr->_capacity;
    list = ptr->list;
    return *this;
}

List List::operator()(List::pos_t st, List::pos_t ed) const
{
    if (st >= (pos_t)_length || -st > (pos_t)_length || ed >= (pos_t)_length || -ed > (pos_t)_length)
        return *(new List());
    if (st < 0)
        st = (pos_t)_length + st;
    if (ed < 0)
        ed = (pos_t)_length + ed + 1;
    if (st >= ed)
        return *(new List());
    List *ret = new List(ed - st);
    for (size_t i = 0; i < ret->_length; i++)
    {
        ret->list[i] = *list[i + st].clone();
    }
    return *ret;
}

typename List::Any List::operator()(List::pos_t index) const
{
    if (index < 0)
    {
        index += _length;
    }
    if (index < 0 || index >= (pos_t)_length)
    {
        throw "Index Out Of Bounds Exception";
    }
    return list[index];
}

typename List::Iterator List::begin()
{
    return Iterator(&list[0]);
}
typename List::Iterator List::end()
{
    return Iterator(&list[_length]);
}

class Tester
{
private:
    int val;

public:
    int &data()
    {
        return val;
    }
    Tester(int x = 0) : val(x) {}
};

int main()
{
    List t;
    t.add(0.5);
    t.add(1.6);
    t.add(2.7);
    t.add(3.8);
    t.add(4.4);
    t.add("Test");
    t.add(Tester(15));
    t.add(5.6);
    t.add(6.4);
    List q = t(0, 5) + t(-2, -1);
    for (auto x : q)
    {
        std::cout << double(x) << std::endl;
    }
    std::cout << t[5].cast<std::string>() << std::endl;
    std::cout << t[6].cast<Tester>().data() << std::endl;

    system("pause");
}