#include "alloc/easy.hpp"
#include "alloc/linear.hpp"
#include "buffer/simple.hpp"
#include "tap.hpp"

#include <cstdlib>


///////////////////////////////////////////////////////////////////////////////
struct setter {
    setter (const setter&) = delete;

    setter (bool &_target):
        target (_target)
    { target = false; }

    ~setter ()
    { target = true; }

    bool &target;
};


///////////////////////////////////////////////////////////////////////////////
int main ()
{
    static constexpr std::size_t elements = 4096;
    cruft::buffer::simple buf (elements);

    cruft::alloc::easy::owned <
        cruft::alloc::linear,
        cruft::buffer::simple
    > alloc (
        std::move (buf)
    );

    cruft::TAP::logger tap;

    bool flag = true;

    // double check our testing object is working, because I'm tired and stupid
    {
        setter val (flag);
        CHECK (!flag);
    }
    CHECK (flag);

    // ensure manual acquire and release calls constructors and destructors
    {
        auto obj = alloc.acquire<setter> (flag);
        tap.expect_eq (flag, false, "backed::acquire calls constructor");

        alloc.release (obj);
        tap.expect_eq (flag, true, "backed::release calls destructor");
    }

    // ensure unique_ptr like objects call constructors and destructors
    {
        auto obj = alloc.unique<setter> (flag);
        tap.expect_eq (flag, false, "backed::unique acquire calls constructor");
    }

    tap.expect_eq (flag, true, "backed::unique release calls destructor");

    return tap.status ();
}