#include <vector>
#include <iostream>
#include <functional>

using namespace std;

class Element;
using VElement = Element*;  //widok na obiekt, nie zarzadza obiektem
//Powinno być (C++17): using VElement = reference_wrapper<Element>
//ale w tym zadaniu poprzednia definicja wystarczy
using Elements = vector<VElement>;

class File;
class Dir;

class Visitor {
public:
    virtual void visit(const File& f) = 0;
    virtual void visit(const Dir& d) = 0;
};

class Element {
public:
    virtual ~Element() = default;
    virtual void accept(Visitor& v) const = 0;
};
class File : public Element {
public:
    File(size_t size) : size_(size) {}
    void accept(Visitor& v) const override { v.visit(*this); }
    size_t getSize() const { return size_; }
private:
    size_t size_;
};

class Dir : public Element {
public:
    Dir() {}
    void accept(Visitor& v) const override { v.visit(*this); }

    const Elements& getChildren() const { return children_; }
private:
    Elements children_;
};

size_t getSize(const Elements& v) {
    const size_t DIR_SIZE = 1024;

    struct VisitorSize : public Visitor {
        VisitorSize() : size_(0) {}

        void visit(const File& f) override {
            size_ += f.getSize();
        }
        void visit(const Dir& d) override {
            size_ += DIR_SIZE + getSize(d.getChildren());
        }
        size_t size_;
    } vis;

    for(const VElement& e : v ) {
        e->accept(vis);
    }
    return vis.size_;
}


int main() {
    return 0;
}
