/*
 * 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::alloc {
    // allocator that always fails, throwing bad_alloc. deallocate will
    // succeed with nullptr as with delete, but is undefined with other values
    // (it is likely to at least assert).
    class null {
    public:
        null () = default;
        null (const null&) = delete;
        null& operator= (const null&) = delete;

        template <typename T>
        cruft::view<T*>
        allocate (size_t count)
        {
            return allocate<T> (count, alignof (T));
        }

        template <typename T>
        cruft::view<T*>
        allocate (size_t count, size_t align)
        {
            (void)count;
            (void)align;

            throw std::bad_alloc ();
        }

        template <typename T>
        void
        deallocate (cruft::view<T*> ptr)
        {
            (void)ptr;
            CHECK_EQ (ptr.data (), static_cast<const void*> (nullptr));
        }

        cruft::view<std::byte*> data (void);
        cruft::view<const std::byte*> data (void) const;

        std::byte* begin (void);
        const std::byte* begin (void) const;
        std::byte* end (void);
        const std::byte* end (void) const;

        size_t offset (const void*) const;

        void reset (void);

        size_t capacity (void) const;
        size_t used     (void) const;
        size_t remain   (void) const;
    };
}