#include <vector>
#include <memory>

typedef std::vector<int> CBuffer;

static CBuffer& PostProcess(CBuffer& data)  { 
    for(auto& el : data)
        el /= 2;
    return data;
}

struct CSource
{
    CSource() : _data(std::make_shared<CBuffer>(10)) {}

    std::shared_ptr<CBuffer>       GetData()       { return _data; }
    std::shared_ptr<const CBuffer> GetData() const { return _data; }

  private:
    std::shared_ptr<CBuffer> _data;
};

struct CPlug
{
    CPlug(bool postProcess = true) : m_postProcess(postProcess) { }

    std::shared_ptr<const CBuffer> ProcessData() const
    {
        /* get the data from the source, implicitely const */
        auto buffer = m_source.GetData();

        if (!m_postProcess)
            return buffer;

        // clone!
        auto clone = *buffer;
        return std::make_shared<CBuffer>(PostProcess(clone));
    }

  private:
    bool    m_postProcess;
    CSource m_source;
};

int main()
{
    CPlug intance;
    auto x = instance.ProcessData();
}
