/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * Copyright 2015 Danny Robson <danny@nerdcruft.net>
 */

#pragma once

#include "../view.hpp"

#include <cstddef>

namespace cruft::buffer {
    // buffer size is advisory and will likely depend on page size. the user
    // must check the size after creation if this field is important for
    // their usage.
    template <typename ValueT>
    class circular {
    public:
        using value_type = ValueT;
        using iterator = value_type*;
        using const_iterator = const value_type*;

        explicit circular (size_t bytes);
        ~circular ();

        circular (const circular&) = delete;
        circular (circular&&) = delete;
        circular& operator= (const circular&) = delete;
        circular& operator= (circular&&) = delete;

        value_type& operator[] (size_t)&;
        const value_type& operator[] (size_t) const&;

        iterator begin (void)&;
        iterator end   (void)&;

        const_iterator begin (void) const&;
        const_iterator end   (void) const&;

        size_t size (void) const;

        /// rebases the pointer so that it points to within the first
        /// repetition of the data buffer.
        iterator constrain (iterator);
        /// rebases a pair of pointers so they fall within a contiguous span of
        /// the data buffer.
        cruft::view<iterator> constrain (cruft::view<iterator>);

    private:
        value_type *m_begin, *m_end;

    };
}