<commit_before>#include <pyglue.h>
#include <common/Common.h>
#include <cuda/CUDABipartiteGraphBFSearcher.h>
#include <string.h>

static PyObject *Cuda_BgBfSearcherError;
namespace sq = sqaod;
namespace sqcu = sqaod_cuda;

namespace {

template<class real>
sqcu::CUDABipartiteGraphBFSearcher<real> *pyobjToCppObj(PyObject *obj) {
    npy_uint64 val = PyArrayScalar_VAL(obj, UInt64);
    return reinterpret_cast<sqcu::CUDABipartiteGraphBFSearcher<real>*>(val);
}

extern "C"
PyObject *bg_bf_searcher_create(PyObject *module, PyObject *args) {
    PyObject *dtype;
    void *ext;
    if (!PyArg_ParseTuple(args, "O", &dtype))
        return NULL;
    if (isFloat64(dtype))
        ext = (void*)new sqcu::CUDABipartiteGraphBFSearcher<double>();
    else if (isFloat32(dtype))
        ext = (void*)new sqcu::CUDABipartiteGraphBFSearcher<float>();
    else
        RAISE_INVALID_DTYPE(dtype, Cuda_BgBfSearcherError);

    PyObject *obj = PyArrayScalar_New(UInt64);
    PyArrayScalar_ASSIGN(obj, UInt64, (npy_uint64)ext);
    Py_INCREF(obj);
    return obj;
}

extern "C"
PyObject *bg_bf_searcher_delete(PyObject *module, PyObject *args) {
    PyObject *objExt, *dtype;
    if (!PyArg_ParseTuple(args, "OO", &objExt, &dtype))
        return NULL;
    if (isFloat64(dtype))
        delete pyobjToCppObj<double>(objExt);
    else if (isFloat32(dtype))
        delete pyobjToCppObj<float>(objExt);
    else
        RAISE_INVALID_DTYPE(dtype, Cuda_BgBfSearcherError);

    Py_INCREF(Py_None);
    return Py_None;

extern "C"
PyObject *bg_bf_searcher_assign_device(PyObject *module, PyObject *args) {
    PyObject *objExt, *objDevice, *dtype;
    if (!PyArg_ParseTuple(args, "OOO", &objExt, &objDevice, &dtype))
        return NULL;

    sqcu::Device *device = (sqcu::Device*)PyArrayScalar_VAL(objDevice, UInt64);
    if (isFloat64(dtype))
        pyobjToCppObj<double>(objExt)->assignDevice(*device);
    else if (isFloat32(dtype))
        pyobjToCppObj<float>(objExt)->assignDevice(*device);
    else
        RAISE_INVALID_DTYPE(dtype, Cuda_BgBfSearcherError);

    Py_INCREF(Py_None);
    return Py_None;
}

template<class real>
void internal_bg_bf_searcher_set_problem(PyObject *objExt,
                                       PyObject *objB0, PyObject *objB1, PyObject *objW, int opt) {
    typedef NpMatrixType<real> NpMatrix;
    typedef NpVectorType<real> NpVector;
    NpVector b0(objB0), b1(objB1);
    NpMatrix W(objW);
    sq::OptimizeMethod om = (opt == 0) ? sq::optMinimize : sq::optMaximize;
    pyobjToCppObj<real>(objExt)->setProblem(b0, b1, W, om);
}

extern "C"
PyObject *bg_bf_searcher_set_problem(PyObject *module, PyObject *args) {
    PyObject *objExt, *objB0, *objB1, *objW, *dtype;
    int opt;
    if (!PyArg_ParseTuple(args, "OOOOiO", &objExt, &objB0, &objB1, &objW, &opt, &dtype))
        return NULL;

    TRY {
        if (isFloat64(dtype))
            internal_bg_bf_searcher_set_problem<double>(objExt, objB0, objB1, objW, opt);
        else if (isFloat32(dtype))
            internal_bg_bf_searcher_set_problem<float>(objExt, objB0, objB1, objW, opt);
        else
            RAISE_INVALID_DTYPE(dtype, Cuda_BgBfSearcherError);
    } CATCH_ERROR_AND_RETURN(Cuda_BgBfSearcherError);

    Py_INCREF(Py_None);
    return Py_None;
}

extern "C"
PyObject *bg_bf_searcher_set_preferences(PyObject *module, PyObject *args) {
    PyObject *objExt, *dtype, *objPrefs;
    if (!PyArg_ParseTuple(args, "OOO", &objExt, &objPrefs, &dtype))
        return NULL;

    sq::Preferences prefs;
    if (parsePreferences(objPrefs, &prefs, Cuda_BgBfSearcherError) == -1)
        return NULL;

    TRY {
        if (isFloat64(dtype))
            pyobjToCppObj<double>(objExt)->setPreferences(prefs);
        else if (isFloat32(dtype))
            pyobjToCppObj<float>(objExt)->setPreferences(prefs);
        else
            RAISE_INVALID_DTYPE(dtype, Cuda_BgBfSearcherError);
    } CATCH_ERROR_AND_RETURN(Cuda_BgBfSearcherError);

    Py_INCREF(Py_None);
    return Py_None;
}

extern "C"
PyObject *bg_bf_searcher_get_preferences(PyObject *module, PyObject *args) {
    PyObject *objExt, *dtype;
    if (!PyArg_ParseTuple(args, "OO", &objExt, &dtype))
        return NULL;

    sq::Preferences prefs;

    TRY {
        if (isFloat64(dtype))
            prefs = pyobjToCppObj<double>(objExt)->getPreferences();
        else if (isFloat32(dtype))
            prefs = pyobjToCppObj<float>(objExt)->getPreferences();
        else
            RAISE_INVALID_DTYPE(dtype, Cuda_BgBfSearcherError);
    } CATCH_ERROR_AND_RETURN(Cuda_BgBfSearcherError);

    return createPreferences(prefs);
}

template<class real>
PyObject *internal_bg_bf_searcher_get_x(PyObject *objExt) {
    sqcu::CUDABipartiteGraphBFSearcher<real> *sol = pyobjToCppObj<real>(objExt);
    const sq::BitsPairArray &xList = sol->get_x();

    sq::SizeType N0, N1;
    sol->getProblemSize(&N0, &N1);

    PyObject *list = PyList_New(xList.size());
    for (size_t idx = 0; idx < xList.size(); ++idx) {
        const sq::BitsPairArray::ValueType &pair = xList[idx];
        NpBitVector x0(N0, NPY_INT8), x1(N1, NPY_INT8);
        x0.vec = pair.first;
        x1.vec = pair.second;

        PyObject *tuple = PyTuple_New(2);
        PyTuple_SET_ITEM(tuple, 0, x0.obj);
        PyTuple_SET_ITEM(tuple, 1, x1.obj);
        PyList_SET_ITEM(list, idx, tuple);
    }
    return list;
}

extern "C"
PyObject *bg_bf_searcher_get_x(PyObject *module, PyObject *args) {
    PyObject *objExt, *dtype;
    if (!PyArg_ParseTuple(args, "OO", &objExt, &dtype))
        return NULL;

    TRY {
        if (isFloat64(dtype))
            return internal_bg_bf_searcher_get_x<double>(objExt);
        else if (isFloat32(dtype))
            return internal_bg_bf_searcher_get_x<float>(objExt);
    } CATCH_ERROR_AND_RETURN(Cuda_BgBfSearcherError);

    RAISE_INVALID_DTYPE(dtype, Cuda_BgBfSearcherError);
}

template<class real>
PyObject *internal_bg_bf_searcher_get_E(PyObject *objExt, int typenum) {
    typedef NpVectorType<real> NpVector;
    const sqaod::VectorType<real> &E = pyobjToCppObj<real>(objExt)->get_E();
    NpVector npE(E.size, typenum); /* allocate PyObject */
    npE.vec = E;
    return npE.obj;
}

extern "C"
PyObject *bg_bf_searcher_get_E(PyObject *module, PyObject *args) {
    PyObject *objExt, *dtype;
    if (!PyArg_ParseTuple(args, "OO", &objExt, &dtype))
        return NULL;

    TRY {
        if (isFloat64(dtype))
            return internal_bg_bf_searcher_get_E<double>(objExt, NPY_FLOAT64);
        else if (isFloat32(dtype))
            return internal_bg_bf_searcher_get_E<float>(objExt, NPY_FLOAT32);
    } CATCH_ERROR_AND_RETURN(Cuda_BgBfSearcherError);

    RAISE_INVALID_DTYPE(dtype, Cuda_BgBfSearcherError);
}

extern "C"
PyObject *bg_bf_searcher_init_search(PyObject *module, PyObject *args) {
    PyObject *objExt, *dtype;
    if (!PyArg_ParseTuple(args, "OO", &objExt, &dtype))
        return NULL;

    TRY {
        if (isFloat64(dtype))
            pyobjToCppObj<double>(objExt)->initSearch();
        else if (isFloat32(dtype))
            pyobjToCppObj<float>(objExt)->initSearch();
        else
            RAISE_INVALID_DTYPE(dtype, Cuda_BgBfSearcherError);
    } CATCH_ERROR_AND_RETURN(Cuda_BgBfSearcherError);

    Py_INCREF(Py_None);
    return Py_None;
}

extern "C"
PyObject *bg_bf_searcher_fin_search(PyObject *module, PyObject *args) {
    PyObject *objExt, *dtype;
    if (!PyArg_ParseTuple(args, "OO", &objExt, &dtype))
        return NULL;

    TRY {
        if (isFloat64(dtype))
            pyobjToCppObj<double>(objExt)->finSearch();
        else if (isFloat32(dtype))
            pyobjToCppObj<float>(objExt)->finSearch();
        else
            RAISE_INVALID_DTYPE(dtype, Cuda_BgBfSearcherError);
    } CATCH_ERROR_AND_RETURN(Cuda_BgBfSearcherError);

    Py_INCREF(Py_None);
    return Py_None;
}

extern "C"
PyObject *bg_bf_searcher_search_range(PyObject *module, PyObject *args) {
    PyObject *objExt, *dtype;
    unsigned long long iBegin0, iEnd0, iBegin1, iEnd1;
    if (!PyArg_ParseTuple(args, "OKKKKO", &objExt, &iBegin0, &iEnd0, &iBegin1, &iEnd1, &dtype))
        return NULL;

    TRY {
        if (isFloat64(dtype))
            pyobjToCppObj<double>(objExt)->searchRange(iBegin0, iEnd0, iBegin1, iEnd1);
        else if (isFloat32(dtype))
            pyobjToCppObj<float>(objExt)->searchRange(iBegin0, iEnd0, iBegin1, iEnd1);
        else
            RAISE_INVALID_DTYPE(dtype, Cuda_BgBfSearcherError);
    } CATCH_ERROR_AND_RETURN(Cuda_BgBfSearcherError);

    Py_INCREF(Py_None);
    return Py_None;
}

extern "C"
PyObject *bg_bf_searcher_search(PyObject *module, PyObject *args) {
    PyObject *objExt, *dtype;
    if (!PyArg_ParseTuple(args, "OO", &objExt, &dtype))
        return NULL;

    TRY {
        if (isFloat64(dtype))
            pyobjToCppObj<double>(objExt)->search();
        else if (isFloat32(dtype))
            pyobjToCppObj<float>(objExt)->search();
        else
            RAISE_INVALID_DTYPE(dtype, Cuda_BgBfSearcherError);
    } CATCH_ERROR_AND_RETURN(Cuda_BgBfSearcherError);

    Py_INCREF(Py_None);
    return Py_None;
}

}

static
PyMethodDef cuda_bg_bf_searcher_methods[] = {
	{"new_searcher", bg_bf_searcher_create, METH_VARARGS},
	{"delete_searcher", bg_bf_searcher_delete, METH_VARARGS},
	{"set_problem", bg_bf_searcher_set_problem, METH_VARARGS},
	{"set_preferences", bg_bf_searcher_set_preferences, METH_VARARGS},
	{"get_preferences", bg_bf_searcher_get_preferences, METH_VARARGS},
	{"get_x", bg_bf_searcher_get_x, METH_VARARGS},
	{"get_E", bg_bf_searcher_get_E, METH_VARARGS},
	{"init_search", bg_bf_searcher_init_search, METH_VARARGS},
	{"fin_search", bg_bf_searcher_fin_search, METH_VARARGS},
	{"search_range", bg_bf_searcher_search_range, METH_VARARGS},
	{"search", bg_bf_searcher_search, METH_VARARGS},
	{NULL},
    {"assign_device", bg_bf_searcher_assign_device, METH_VARARGS},
};

extern "C"
PyMODINIT_FUNC
initcuda_bg_bf_searcher(void) {
    PyObject *m;

    m = Py_InitModule("cuda_bg_bf_searcher", cuda_bg_bf_searcher_methods);
    import_array();
    if (m == NULL)
        return;

    char name[] = "cuda_bg_searcher.error";
    Cuda_BgBfSearcherError = PyErr_NewException(name, NULL, NULL);
    Py_INCREF(Cuda_BgBfSearcherError);
    PyModule_AddObject(m, "error", Cuda_BgBfSearcherError);
}
<commit_msg>trivial.<commit_after>#include <pyglue.h>
#include <common/Common.h>
#include <cuda/CUDABipartiteGraphBFSearcher.h>
#include <string.h>

static PyObject *Cuda_BgBfSearcherError;
namespace sq = sqaod;
namespace sqcu = sqaod_cuda;

namespace {

template<class real>
sqcu::CUDABipartiteGraphBFSearcher<real> *pyobjToCppObj(PyObject *obj) {
    npy_uint64 val = PyArrayScalar_VAL(obj, UInt64);
    return reinterpret_cast<sqcu::CUDABipartiteGraphBFSearcher<real>*>(val);
}

extern "C"
PyObject *bg_bf_searcher_create(PyObject *module, PyObject *args) {
    PyObject *dtype;
    void *ext;
    if (!PyArg_ParseTuple(args, "O", &dtype))
        return NULL;
    if (isFloat64(dtype))
        ext = (void*)new sqcu::CUDABipartiteGraphBFSearcher<double>();
    else if (isFloat32(dtype))
        ext = (void*)new sqcu::CUDABipartiteGraphBFSearcher<float>();
    else
        RAISE_INVALID_DTYPE(dtype, Cuda_BgBfSearcherError);

    PyObject *obj = PyArrayScalar_New(UInt64);
    PyArrayScalar_ASSIGN(obj, UInt64, (npy_uint64)ext);
    Py_INCREF(obj);
    return obj;
}

extern "C"
PyObject *bg_bf_searcher_delete(PyObject *module, PyObject *args) {
    PyObject *objExt, *dtype;
    if (!PyArg_ParseTuple(args, "OO", &objExt, &dtype))
        return NULL;
    if (isFloat64(dtype))
        delete pyobjToCppObj<double>(objExt);
    else if (isFloat32(dtype))
        delete pyobjToCppObj<float>(objExt);
    else
        RAISE_INVALID_DTYPE(dtype, Cuda_BgBfSearcherError);

    Py_INCREF(Py_None);
    return Py_None;
}

extern "C"
PyObject *bg_bf_searcher_assign_device(PyObject *module, PyObject *args) {
    PyObject *objExt, *objDevice, *dtype;
    if (!PyArg_ParseTuple(args, "OOO", &objExt, &objDevice, &dtype))
        return NULL;

    sqcu::Device *device = (sqcu::Device*)PyArrayScalar_VAL(objDevice, UInt64);
    if (isFloat64(dtype))
        pyobjToCppObj<double>(objExt)->assignDevice(*device);
    else if (isFloat32(dtype))
        pyobjToCppObj<float>(objExt)->assignDevice(*device);
    else
        RAISE_INVALID_DTYPE(dtype, Cuda_BgBfSearcherError);

    Py_INCREF(Py_None);
    return Py_None;
}

template<class real>
void internal_bg_bf_searcher_set_problem(PyObject *objExt,
                                       PyObject *objB0, PyObject *objB1, PyObject *objW, int opt) {
    typedef NpMatrixType<real> NpMatrix;
    typedef NpVectorType<real> NpVector;
    NpVector b0(objB0), b1(objB1);
    NpMatrix W(objW);
    sq::OptimizeMethod om = (opt == 0) ? sq::optMinimize : sq::optMaximize;
    pyobjToCppObj<real>(objExt)->setProblem(b0, b1, W, om);
}

extern "C"
PyObject *bg_bf_searcher_set_problem(PyObject *module, PyObject *args) {
    PyObject *objExt, *objB0, *objB1, *objW, *dtype;
    int opt;
    if (!PyArg_ParseTuple(args, "OOOOiO", &objExt, &objB0, &objB1, &objW, &opt, &dtype))
        return NULL;

    TRY {
        if (isFloat64(dtype))
            internal_bg_bf_searcher_set_problem<double>(objExt, objB0, objB1, objW, opt);
        else if (isFloat32(dtype))
            internal_bg_bf_searcher_set_problem<float>(objExt, objB0, objB1, objW, opt);
        else
            RAISE_INVALID_DTYPE(dtype, Cuda_BgBfSearcherError);
    } CATCH_ERROR_AND_RETURN(Cuda_BgBfSearcherError);

    Py_INCREF(Py_None);
    return Py_None;
}

extern "C"
PyObject *bg_bf_searcher_set_preferences(PyObject *module, PyObject *args) {
    PyObject *objExt, *dtype, *objPrefs;
    if (!PyArg_ParseTuple(args, "OOO", &objExt, &objPrefs, &dtype))
        return NULL;

    sq::Preferences prefs;
    if (parsePreferences(objPrefs, &prefs, Cuda_BgBfSearcherError) == -1)
        return NULL;

    TRY {
        if (isFloat64(dtype))
            pyobjToCppObj<double>(objExt)->setPreferences(prefs);
        else if (isFloat32(dtype))
            pyobjToCppObj<float>(objExt)->setPreferences(prefs);
        else
            RAISE_INVALID_DTYPE(dtype, Cuda_BgBfSearcherError);
    } CATCH_ERROR_AND_RETURN(Cuda_BgBfSearcherError);

    Py_INCREF(Py_None);
    return Py_None;
}

extern "C"
PyObject *bg_bf_searcher_get_preferences(PyObject *module, PyObject *args) {
    PyObject *objExt, *dtype;
    if (!PyArg_ParseTuple(args, "OO", &objExt, &dtype))
        return NULL;

    sq::Preferences prefs;

    TRY {
        if (isFloat64(dtype))
            prefs = pyobjToCppObj<double>(objExt)->getPreferences();
        else if (isFloat32(dtype))
            prefs = pyobjToCppObj<float>(objExt)->getPreferences();
        else
            RAISE_INVALID_DTYPE(dtype, Cuda_BgBfSearcherError);
    } CATCH_ERROR_AND_RETURN(Cuda_BgBfSearcherError);

    return createPreferences(prefs);
}

template<class real>
PyObject *internal_bg_bf_searcher_get_x(PyObject *objExt) {
    sqcu::CUDABipartiteGraphBFSearcher<real> *sol = pyobjToCppObj<real>(objExt);
    const sq::BitsPairArray &xList = sol->get_x();

    sq::SizeType N0, N1;
    sol->getProblemSize(&N0, &N1);

    PyObject *list = PyList_New(xList.size());
    for (size_t idx = 0; idx < xList.size(); ++idx) {
        const sq::BitsPairArray::ValueType &pair = xList[idx];
        NpBitVector x0(N0, NPY_INT8), x1(N1, NPY_INT8);
        x0.vec = pair.first;
        x1.vec = pair.second;

        PyObject *tuple = PyTuple_New(2);
        PyTuple_SET_ITEM(tuple, 0, x0.obj);
        PyTuple_SET_ITEM(tuple, 1, x1.obj);
        PyList_SET_ITEM(list, idx, tuple);
    }
    return list;
}

extern "C"
PyObject *bg_bf_searcher_get_x(PyObject *module, PyObject *args) {
    PyObject *objExt, *dtype;
    if (!PyArg_ParseTuple(args, "OO", &objExt, &dtype))
        return NULL;

    TRY {
        if (isFloat64(dtype))
            return internal_bg_bf_searcher_get_x<double>(objExt);
        else if (isFloat32(dtype))
            return internal_bg_bf_searcher_get_x<float>(objExt);
    } CATCH_ERROR_AND_RETURN(Cuda_BgBfSearcherError);

    RAISE_INVALID_DTYPE(dtype, Cuda_BgBfSearcherError);
}

template<class real>
PyObject *internal_bg_bf_searcher_get_E(PyObject *objExt, int typenum) {
    typedef NpVectorType<real> NpVector;
    const sqaod::VectorType<real> &E = pyobjToCppObj<real>(objExt)->get_E();
    NpVector npE(E.size, typenum); /* allocate PyObject */
    npE.vec = E;
    return npE.obj;
}

extern "C"
PyObject *bg_bf_searcher_get_E(PyObject *module, PyObject *args) {
    PyObject *objExt, *dtype;
    if (!PyArg_ParseTuple(args, "OO", &objExt, &dtype))
        return NULL;

    TRY {
        if (isFloat64(dtype))
            return internal_bg_bf_searcher_get_E<double>(objExt, NPY_FLOAT64);
        else if (isFloat32(dtype))
            return internal_bg_bf_searcher_get_E<float>(objExt, NPY_FLOAT32);
    } CATCH_ERROR_AND_RETURN(Cuda_BgBfSearcherError);

    RAISE_INVALID_DTYPE(dtype, Cuda_BgBfSearcherError);
}

extern "C"
PyObject *bg_bf_searcher_init_search(PyObject *module, PyObject *args) {
    PyObject *objExt, *dtype;
    if (!PyArg_ParseTuple(args, "OO", &objExt, &dtype))
        return NULL;

    TRY {
        if (isFloat64(dtype))
            pyobjToCppObj<double>(objExt)->initSearch();
        else if (isFloat32(dtype))
            pyobjToCppObj<float>(objExt)->initSearch();
        else
            RAISE_INVALID_DTYPE(dtype, Cuda_BgBfSearcherError);
    } CATCH_ERROR_AND_RETURN(Cuda_BgBfSearcherError);

    Py_INCREF(Py_None);
    return Py_None;
}

extern "C"
PyObject *bg_bf_searcher_fin_search(PyObject *module, PyObject *args) {
    PyObject *objExt, *dtype;
    if (!PyArg_ParseTuple(args, "OO", &objExt, &dtype))
        return NULL;

    TRY {
        if (isFloat64(dtype))
            pyobjToCppObj<double>(objExt)->finSearch();
        else if (isFloat32(dtype))
            pyobjToCppObj<float>(objExt)->finSearch();
        else
            RAISE_INVALID_DTYPE(dtype, Cuda_BgBfSearcherError);
    } CATCH_ERROR_AND_RETURN(Cuda_BgBfSearcherError);

    Py_INCREF(Py_None);
    return Py_None;
}

extern "C"
PyObject *bg_bf_searcher_search_range(PyObject *module, PyObject *args) {
    PyObject *objExt, *dtype;
    unsigned long long iBegin0, iEnd0, iBegin1, iEnd1;
    if (!PyArg_ParseTuple(args, "OKKKKO", &objExt, &iBegin0, &iEnd0, &iBegin1, &iEnd1, &dtype))
        return NULL;

    TRY {
        if (isFloat64(dtype))
            pyobjToCppObj<double>(objExt)->searchRange(iBegin0, iEnd0, iBegin1, iEnd1);
        else if (isFloat32(dtype))
            pyobjToCppObj<float>(objExt)->searchRange(iBegin0, iEnd0, iBegin1, iEnd1);
        else
            RAISE_INVALID_DTYPE(dtype, Cuda_BgBfSearcherError);
    } CATCH_ERROR_AND_RETURN(Cuda_BgBfSearcherError);

    Py_INCREF(Py_None);
    return Py_None;
}

extern "C"
PyObject *bg_bf_searcher_search(PyObject *module, PyObject *args) {
    PyObject *objExt, *dtype;
    if (!PyArg_ParseTuple(args, "OO", &objExt, &dtype))
        return NULL;

    TRY {
        if (isFloat64(dtype))
            pyobjToCppObj<double>(objExt)->search();
        else if (isFloat32(dtype))
            pyobjToCppObj<float>(objExt)->search();
        else
            RAISE_INVALID_DTYPE(dtype, Cuda_BgBfSearcherError);
    } CATCH_ERROR_AND_RETURN(Cuda_BgBfSearcherError);

    Py_INCREF(Py_None);
    return Py_None;
}

}

static
PyMethodDef cuda_bg_bf_searcher_methods[] = {
	{"new_searcher", bg_bf_searcher_create, METH_VARARGS},
	{"delete_searcher", bg_bf_searcher_delete, METH_VARARGS},
	{"set_problem", bg_bf_searcher_set_problem, METH_VARARGS},
	{"set_preferences", bg_bf_searcher_set_preferences, METH_VARARGS},
	{"get_preferences", bg_bf_searcher_get_preferences, METH_VARARGS},
	{"get_x", bg_bf_searcher_get_x, METH_VARARGS},
	{"get_E", bg_bf_searcher_get_E, METH_VARARGS},
	{"init_search", bg_bf_searcher_init_search, METH_VARARGS},
	{"fin_search", bg_bf_searcher_fin_search, METH_VARARGS},
	{"search_range", bg_bf_searcher_search_range, METH_VARARGS},
	{"search", bg_bf_searcher_search, METH_VARARGS},
	{NULL},
    {"assign_device", bg_bf_searcher_assign_device, METH_VARARGS},
};

extern "C"
PyMODINIT_FUNC
initcuda_bg_bf_searcher(void) {
    PyObject *m;

    m = Py_InitModule("cuda_bg_bf_searcher", cuda_bg_bf_searcher_methods);
    import_array();
    if (m == NULL)
        return;

    char name[] = "cuda_bg_searcher.error";
    Cuda_BgBfSearcherError = PyErr_NewException(name, NULL, NULL);
    Py_INCREF(Cuda_BgBfSearcherError);
    PyModule_AddObject(m, "error", Cuda_BgBfSearcherError);
}
<|endoftext|>


<commit_before>#ifndef IMPROC_INSTANCE
#define IMPROC_INSTANCE

#include "singleton_factory.hpp"
#include "instance_factory.hpp"
#include "image_proc.hpp"
#include "ppapi/cpp/var_dictionary.h"
#include "ppapi/cpp/var_array.h"
#include "ppapi/cpp/var_array_buffer.h"
#include "ppapi/utility/completion_callback_factory.h"
#include "ppapi/utility/threading/simple_thread.h"

// The ImageProcInstance that stores
class ImageProcInstance : public pp::Instance {
  public:
    explicit ImageProcInstance( PP_Instance instance )
      : pp::Instance(instance), callback_factory_(this), proc_thread_(this) {};
    virtual ~ImageProcInstance( ){ proc_thread_.Join(); };
    virtual void HandleMessage( const pp::Var& );
    virtual bool Init(uint32_t /*argc*/,
        const char * /*argn*/ [],
        const char * /*argv*/ []) {
      proc_thread_.Start();
      proc_thread_.message_loop().PostWork(
        callback_factory_.NewCallback( &ImageProcInstance::Version ));
      return true;
    }

  private:
    bool run_simulation_;
    std::string processorName; // Name of currently selected processor
    std::unique_ptr<Processor> processor;
    pp::CompletionCallbackFactory<ImageProcInstance> callback_factory_;
    pp::SimpleThread proc_thread_; // Thread for image processor
    void Process(cv::Mat);
    void PostTest();
    void SendStatus(const std::string& status);
    pp::VarDictionary PostResponse( cv::Mat );
    void Version( int32_t ) {
      pp::VarDictionary msg;
      msg.Set( "Type", "version" );
      msg.Set( "Version", "Image Processor 0.4" );
      // Get processor
      auto processorFactory = SingletonFactory<std::function<std::unique_ptr<Processor>()>>::getInstance();
      auto processorList = processorFactory.getNames();
      pp::VarArray msgProcessorList;
      for ( size_t i=0; i < processorList.size(); i ++ ) {
        msgProcessorList.Set( i, processorList[i] );
      }
      msg.Set( "Processors", msgProcessorList );
      PostMessage( msg );
    }
};

#endif
<commit_msg>Bump minor version number.<commit_after>#ifndef IMPROC_INSTANCE
#define IMPROC_INSTANCE

#include "singleton_factory.hpp"
#include "instance_factory.hpp"
#include "image_proc.hpp"
#include "ppapi/cpp/var_dictionary.h"
#include "ppapi/cpp/var_array.h"
#include "ppapi/cpp/var_array_buffer.h"
#include "ppapi/utility/completion_callback_factory.h"
#include "ppapi/utility/threading/simple_thread.h"

// The ImageProcInstance that stores
class ImageProcInstance : public pp::Instance {
  public:
    explicit ImageProcInstance( PP_Instance instance )
      : pp::Instance(instance), callback_factory_(this), proc_thread_(this) {};
    virtual ~ImageProcInstance( ){ proc_thread_.Join(); };
    virtual void HandleMessage( const pp::Var& );
    virtual bool Init(uint32_t /*argc*/,
        const char * /*argn*/ [],
        const char * /*argv*/ []) {
      proc_thread_.Start();
      proc_thread_.message_loop().PostWork(
        callback_factory_.NewCallback( &ImageProcInstance::Version ));
      return true;
    }

  private:
    bool run_simulation_;
    std::string processorName; // Name of currently selected processor
    std::unique_ptr<Processor> processor;
    pp::CompletionCallbackFactory<ImageProcInstance> callback_factory_;
    pp::SimpleThread proc_thread_; // Thread for image processor
    void Process(cv::Mat);
    void PostTest();
    void SendStatus(const std::string& status);
    pp::VarDictionary PostResponse( cv::Mat );
    void Version( int32_t ) {
      pp::VarDictionary msg;
      msg.Set( "Type", "version" );
      msg.Set( "Version", "Image Processor 0.4.1" );
      // Get processor
      auto processorFactory = SingletonFactory<std::function<std::unique_ptr<Processor>()>>::getInstance();
      auto processorList = processorFactory.getNames();
      pp::VarArray msgProcessorList;
      for ( size_t i=0; i < processorList.size(); i ++ ) {
        msgProcessorList.Set( i, processorList[i] );
      }
      msg.Set( "Processors", msgProcessorList );
      PostMessage( msg );
    }
};

#endif
<|endoftext|>


<commit_before>// @(#)root/reflex:$Name:  $:$Id: Array.cxx,v 1.5 2006/03/13 15:49:50 roiser Exp $
// Author: Stefan Roiser 2004

// Copyright CERN, CH-1211 Geneva 23, 2004-2006, All rights reserved.
//
// Permission to use, copy, modify, and distribute this software for any
// purpose is hereby granted without fee, provided that this copyright and
// permissions notice appear in all copies and derivatives.
//
// This software is provided "as is" without express or implied warranty.

#ifndef REFLEX_BUILD
#define REFLEX_BUILD
#endif

#include "Array.h"
#include "Reflex/Type.h"
#include <sstream>

//-------------------------------------------------------------------------------
ROOT::Reflex::Array::Array( const Type & arrayType,
                            size_t len,
                            const std::type_info & typeinfo )
//-------------------------------------------------------------------------------
   : TypeBase( BuildTypeName(arrayType, len ).c_str(),
               len*(arrayType.SizeOf()), ARRAY, typeinfo ),
     fArrayType( arrayType ),
     fLength( len ) { }

//-------------------------------------------------------------------------------
std::string ROOT::Reflex::Array::Name( unsigned int mod ) const {
//-------------------------------------------------------------------------------
   return BuildTypeName( fArrayType, fLength, mod );
}

//-------------------------------------------------------------------------------
std::string ROOT::Reflex::Array::BuildTypeName( const Type & typ,
                                                size_t len,
                                                unsigned int mod ) {
//-------------------------------------------------------------------------------
   std::ostringstream ost;
   ost << typ.Name( mod ) << "[" << len << "]";
   return ost.str();
}
<commit_msg>Add header file needed to compiler with REFLEXDLL on windows<commit_after>// @(#)root/reflex:$Name:  $:$Id: Array.cxx,v 1.6 2006/03/20 09:46:18 roiser Exp $
// Author: Stefan Roiser 2004

// Copyright CERN, CH-1211 Geneva 23, 2004-2006, All rights reserved.
//
// Permission to use, copy, modify, and distribute this software for any
// purpose is hereby granted without fee, provided that this copyright and
// permissions notice appear in all copies and derivatives.
//
// This software is provided "as is" without express or implied warranty.

#ifndef REFLEX_BUILD
#define REFLEX_BUILD
#endif

#include "Array.h"
#include "Reflex/Type.h"
#include "Reflex/Member.h"
#include <sstream>

//-------------------------------------------------------------------------------
ROOT::Reflex::Array::Array( const Type & arrayType,
                            size_t len,
                            const std::type_info & typeinfo )
//-------------------------------------------------------------------------------
   : TypeBase( BuildTypeName(arrayType, len ).c_str(),
               len*(arrayType.SizeOf()), ARRAY, typeinfo ),
     fArrayType( arrayType ),
     fLength( len ) { }

//-------------------------------------------------------------------------------
std::string ROOT::Reflex::Array::Name( unsigned int mod ) const {
//-------------------------------------------------------------------------------
   return BuildTypeName( fArrayType, fLength, mod );
}

//-------------------------------------------------------------------------------
std::string ROOT::Reflex::Array::BuildTypeName( const Type & typ,
                                                size_t len,
                                                unsigned int mod ) {
//-------------------------------------------------------------------------------
   std::ostringstream ost;
   ost << typ.Name( mod ) << "[" << len << "]";
   return ost.str();
}
<|endoftext|>


<commit_before>/**
 * \file
 * \brief testCases object definition
 *
 * \author Copyright (C) 2014-2015 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * 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/.
 *
 * \date 2015-01-19
 */

#include "testCases.hpp"

#include "Thread/threadTestCases.hpp"
#include "SoftwareTimer/softwareTimerTestCases.hpp"
#include "Semaphore/semaphoreTestCases.hpp"
#include "Mutex/mutexTestCases.hpp"
#include "ConditionVariable/conditionVariableTestCases.hpp"
#include "FifoQueue/fifoQueueTestCases.hpp"
#include "RawFifoQueue/rawFifoQueueTestCases.hpp"
#include "MessageQueue/messageQueueTestCases.hpp"
#include "RawMessageQueue/rawMessageQueueTestCases.hpp"

namespace distortos
{

namespace test
{

namespace
{

/*---------------------------------------------------------------------------------------------------------------------+
| local objects
+---------------------------------------------------------------------------------------------------------------------*/

/// array with references to TestCaseRange objects
const TestCaseRangeRange::value_type testCases_[]
{
		TestCaseRangeRange::value_type{threadTestCases},
		TestCaseRangeRange::value_type{softwareTimerTestCases},
		TestCaseRangeRange::value_type{semaphoreTestCases},
		TestCaseRangeRange::value_type{mutexTestCases},
		TestCaseRangeRange::value_type{conditionVariableTestCases},
		TestCaseRangeRange::value_type{fifoQueueTestCases},
		TestCaseRangeRange::value_type{rawFifoQueueTestCases},
		TestCaseRangeRange::value_type{messageQueueTestCases},
		TestCaseRangeRange::value_type{rawMessageQueueTestCases},
};

}	// namespace

/*---------------------------------------------------------------------------------------------------------------------+
| global objects
+---------------------------------------------------------------------------------------------------------------------*/

const TestCaseRangeRange testCases {testCases_};

}	// namespace test

}	// namespace distortos
<commit_msg>test: add signalsTestCases to executed test cases<commit_after>/**
 * \file
 * \brief testCases object definition
 *
 * \author Copyright (C) 2014-2015 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * 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/.
 *
 * \date 2015-02-18
 */

#include "testCases.hpp"

#include "Thread/threadTestCases.hpp"
#include "SoftwareTimer/softwareTimerTestCases.hpp"
#include "Semaphore/semaphoreTestCases.hpp"
#include "Mutex/mutexTestCases.hpp"
#include "ConditionVariable/conditionVariableTestCases.hpp"
#include "FifoQueue/fifoQueueTestCases.hpp"
#include "RawFifoQueue/rawFifoQueueTestCases.hpp"
#include "MessageQueue/messageQueueTestCases.hpp"
#include "RawMessageQueue/rawMessageQueueTestCases.hpp"
#include "Signals/signalsTestCases.hpp"

namespace distortos
{

namespace test
{

namespace
{

/*---------------------------------------------------------------------------------------------------------------------+
| local objects
+---------------------------------------------------------------------------------------------------------------------*/

/// array with references to TestCaseRange objects
const TestCaseRangeRange::value_type testCases_[]
{
		TestCaseRangeRange::value_type{threadTestCases},
		TestCaseRangeRange::value_type{softwareTimerTestCases},
		TestCaseRangeRange::value_type{semaphoreTestCases},
		TestCaseRangeRange::value_type{mutexTestCases},
		TestCaseRangeRange::value_type{conditionVariableTestCases},
		TestCaseRangeRange::value_type{fifoQueueTestCases},
		TestCaseRangeRange::value_type{rawFifoQueueTestCases},
		TestCaseRangeRange::value_type{messageQueueTestCases},
		TestCaseRangeRange::value_type{rawMessageQueueTestCases},
		TestCaseRangeRange::value_type{signalsTestCases},
};

}	// namespace

/*---------------------------------------------------------------------------------------------------------------------+
| global objects
+---------------------------------------------------------------------------------------------------------------------*/

const TestCaseRangeRange testCases {testCases_};

}	// namespace test

}	// namespace distortos
<|endoftext|>


<commit_before>void JetAnalysisManagerLoc()
{
      gSystem->Load("libTree.so");
      gSystem->Load("libGeom.so");
      gSystem->Load("libVMC.so");
      gSystem->Load("libESD.so");
      gSystem->Load("libANALYSIS.so");
      gSystem->Load("libJETAN.so");
     //
    if (gApplication) gApplication->InitializeGraphics();
    // Create the chain
    //
    TChain* chain = new TChain("esdTree");
    chain->Add("/home/morsch/analysis/AliEn/Interactive/esd/001/AliESDs.root");
    chain->Add("/home/morsch/analysis/AliEn/Interactive/esd/002/AliESDs.root");
    //
    // Make the analysis manager
    //
    AliAnalysisManager *mgr  = new AliAnalysisManager("Jet Manager", "Jet Manager");
    AliAODHandler* aodHandler   = new AliAODHandler();
    mgr->SetEventHandler(aodHandler);
    mgr-> SetDebugLevel(10);

    AliAnalysisTaskJets *jetana = new AliAnalysisTaskJets("JetAnalysis");
    jetana->SetDebugLevel(10);
    mgr->AddTask(jetana);

    //
    // Create containers for input/output
    AliAnalysisDataContainer *cinput1 = mgr->CreateContainer("cchain",TChain::Class(),
							     AliAnalysisManager::kInputContainer);

    AliAnalysisDataContainer *coutput1 = mgr->CreateContainer("tree", TTree::Class(),
							      AliAnalysisManager::kOutputContainer, "aod.root");

    mgr->ConnectInput  (jetana,  0, cinput1 );
    mgr->ConnectOutput (jetana,  0, coutput1 );
    //
    // Run the analysis
    //
    mgr->InitAnalysis();
    mgr->PrintStatus();
    mgr->StartAnalysis("local",chain);
}
<commit_msg>Update of loaded libraries.<commit_after>void JetAnalysisManagerLoc()
{
    gSystem->Load("libTree.so");
    gSystem->Load("libGeom.so");
    gSystem->Load("libVMC.so");
    gSystem->Load("libANALYSIS.so");
    gSystem->Load("libAOD.so");
    gSystem->Load("libESD.so");
    gSystem->Load("libJETAN.so");
     //
    if (gApplication) gApplication->InitializeGraphics();
    // Create the chain
    //
    TChain* chain = new TChain("esdTree");
    chain->Add("/home/morsch/analysis/AliEn/Interactive/esd/001/AliESDs.root");
    chain->Add("/home/morsch/analysis/AliEn/Interactive/esd/002/AliESDs.root");
    //
    // Make the analysis manager
    //
    AliAnalysisManager *mgr  = new AliAnalysisManager("Jet Manager", "Jet Manager");
    AliAODHandler* aodHandler   = new AliAODHandler();
    mgr->SetEventHandler(aodHandler);
    mgr-> SetDebugLevel(10);

    AliAnalysisTaskJets *jetana = new AliAnalysisTaskJets("JetAnalysis");
    jetana->SetDebugLevel(10);
    mgr->AddTask(jetana);

    //
    // Create containers for input/output
    AliAnalysisDataContainer *cinput1 = mgr->CreateContainer("cchain",TChain::Class(),
							     AliAnalysisManager::kInputContainer);

    AliAnalysisDataContainer *coutput1 = mgr->CreateContainer("tree", TTree::Class(),
							      AliAnalysisManager::kOutputContainer, "aod.root");

    mgr->ConnectInput  (jetana,  0, cinput1 );
    mgr->ConnectOutput (jetana,  0, coutput1 );
    //
    // Run the analysis
    //
    mgr->InitAnalysis();
    mgr->PrintStatus();
    mgr->StartAnalysis("local",chain);
}
<|endoftext|>


<commit_before>/******************************************************************************
The MIT License(MIT)

Embedded Template Library.
https://github.com/ETLCPP/etl

Copyright(c) 2014 jwellbelove

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/

#include <UnitTest++/UnitTest++.h>
#include "ExtraCheckMacros.h"

#include "data.h"

#include <set>
#include <vector>

#include "../pool.h"

typedef TestDataDC<std::string>  Test_Data;
typedef TestDataNDC<std::string> Test_Data2;

namespace
{
  SUITE(test_pool)
  {
    //*************************************************************************
    TEST(test_allocate)
    {
      etl::pool<Test_Data, 4> pool;

      Test_Data* p1;
      Test_Data* p2;
      Test_Data* p3;
      Test_Data* p4;

      CHECK_NO_THROW(p1 = pool.allocate());
      CHECK_NO_THROW(p2 = pool.allocate());
      CHECK_NO_THROW(p3 = pool.allocate());
      CHECK_NO_THROW(p4 = pool.allocate());

      CHECK(p1 != p2);
      CHECK(p1 != p3);
      CHECK(p1 != p4);
      CHECK(p2 != p3);
      CHECK(p2 != p4);
      CHECK(p3 != p4);

      CHECK_THROW(pool.allocate(), etl::pool_no_allocation);
    }

    //*************************************************************************
    TEST(test_release)
    {
      etl::pool<Test_Data, 4> pool;

      Test_Data* p1 = pool.allocate();
      Test_Data* p2 = pool.allocate();
      Test_Data* p3 = pool.allocate();
      Test_Data* p4 = pool.allocate();

      CHECK_NO_THROW(pool.release(p2));
      CHECK_NO_THROW(pool.release(*p3));
      CHECK_NO_THROW(pool.release(p1));
      CHECK_NO_THROW(pool.release(*p4));

      CHECK_EQUAL(4, pool.available());

      Test_Data not_in_pool;

      CHECK_THROW(pool.release(not_in_pool), etl::pool_object_not_in_pool);
    }

    //*************************************************************************
    TEST(test_allocate_release)
    {
      etl::pool<Test_Data, 4> pool;

      Test_Data* p1 = pool.allocate();
      Test_Data* p2 = pool.allocate();
      Test_Data* p3 = pool.allocate();
      Test_Data* p4 = pool.allocate();

      // Allocated p1, p2, p3, p4

      CHECK_EQUAL(0, pool.available());

      CHECK_NO_THROW(pool.release(p2));
      CHECK_NO_THROW(pool.release(p3));

      // Allocated p1, p4

      CHECK_EQUAL(2, pool.available());

      Test_Data* p5 = pool.allocate();
      Test_Data* p6 = pool.allocate();

      // Allocated p1, p4, p5, p6

      CHECK_EQUAL(0, pool.available());

      CHECK(p5 != p1);
      CHECK(p5 != p4);

      CHECK(p6 != p1);
      CHECK(p6 != p4);

      CHECK_NO_THROW(pool.release(p5));

      // Allocated p1, p4, p6

      CHECK_EQUAL(1, pool.available());

      Test_Data* p7 = pool.allocate();

      // Allocated p1, p4, p6, p7

      CHECK(p7 != p1);
      CHECK(p7 != p4);
      CHECK(p7 != p6);

      CHECK(pool.none_free());
    }

    //*************************************************************************
    TEST(test_available)
    {
      etl::pool<Test_Data, 4> pool;
      CHECK_EQUAL(4, pool.available());

      Test_Data* p;

      p = pool.allocate();
      CHECK_EQUAL(3, pool.available());

      p = pool.allocate();
      CHECK_EQUAL(2, pool.available());

      p = pool.allocate();
      CHECK_EQUAL(1, pool.available());

      p = pool.allocate();
      CHECK_EQUAL(0, pool.available());
    }

    //*************************************************************************
    TEST(test_none_free)
    {
      etl::pool<Test_Data, 4> pool;
      CHECK_EQUAL(4, pool.available());

      Test_Data* p;

      p = pool.allocate();
      CHECK(!pool.none_free());

      p = pool.allocate();
      CHECK(!pool.none_free());

      p = pool.allocate();
      CHECK(!pool.none_free());

      p = pool.allocate();
      CHECK(pool.none_free());
    }

    //*************************************************************************
    TEST(test_is_in_pool)
    {
      etl::pool<Test_Data, 4> pool;
      Test_Data not_in_pool;

      Test_Data* p1 = pool.allocate();

      CHECK(pool.is_in_pool(p1));
      CHECK(!pool.is_in_pool(not_in_pool));
    }

    //*************************************************************************
    TEST(test_const_iterator)
    {
      etl::pool<Test_Data2, 10> pool;

      std::set<Test_Data2>     compare = { Test_Data2("0"), Test_Data2("2"), Test_Data2("4"), Test_Data2("6"), Test_Data2("8") };
      std::set<Test_Data2>     test;
      std::vector<Test_Data2*> objects;

      // Build the set of objects.
      objects.push_back(pool.allocate(Test_Data2("9")));
      objects.push_back(pool.allocate(Test_Data2("7")));
      objects.push_back(pool.allocate(Test_Data2("8")));
      objects.push_back(pool.allocate(Test_Data2("6")));
      objects.push_back(pool.allocate(Test_Data2("5")));
      objects.push_back(pool.allocate(Test_Data2("3")));
      objects.push_back(pool.allocate(Test_Data2("4")));
      objects.push_back(pool.allocate(Test_Data2("2")));
      objects.push_back(pool.allocate(Test_Data2("0")));
      objects.push_back(pool.allocate(Test_Data2("1")));

      // Release "1", "3", "5", "7", "9".
      pool.release(objects[0]);
      pool.release(objects[1]);
      pool.release(objects[4]);
      pool.release(objects[5]);
      pool.release(objects[9]);

      // Fill the test set with what we get from the iterator.
      etl::pool<Test_Data2, 10>::const_iterator i_pool = pool.begin();

      while (i_pool != pool.end())
      {
        test.insert(*i_pool);
        ++i_pool;
      }

      // Compare the results.
      std::set<Test_Data2>::const_iterator i_compare = compare.begin();
      std::set<Test_Data2>::const_iterator i_test    = test.begin();

      CHECK_EQUAL(compare.size(), test.size());

      while ((i_compare != compare.end()) && (i_test != test.end()))
      {
        CHECK_EQUAL(*i_compare++, *i_test++);
      }
    }

    //*************************************************************************
    TEST(test_get_iterator)
    {
      typedef etl::pool<Test_Data, 4> Pool;

      Pool pool;
      Test_Data not_in_pool;

      Test_Data* p1 = pool.allocate();
      Test_Data* p2 = pool.allocate();

      Pool::iterator i_data  = pool.get_iterator(*p1);
      Pool::iterator i_ndata = pool.get_iterator(not_in_pool);

      CHECK(p1 == &*i_data);
      CHECK(p2 != &*i_data);
      CHECK(pool.end() == i_ndata);
    }

    //*************************************************************************
    TEST(test_get_iterator_const)
    {
      typedef etl::pool<Test_Data, 4> Pool;

      Pool pool;
      const Test_Data not_in_pool;

      const Test_Data* p1 = pool.allocate();
      const Test_Data* p2 = pool.allocate();

      Pool::const_iterator i_data = pool.get_iterator(*p1);
      Pool::const_iterator i_ndata = pool.get_iterator(not_in_pool);

      CHECK(p1 == &*i_data);
      CHECK(p2 != &*i_data);
      CHECK(pool.end() == i_ndata);
    }
  };
}
<commit_msg>Commented out un-implemented 'get_iterator()' tests.<commit_after>/******************************************************************************
The MIT License(MIT)

Embedded Template Library.
https://github.com/ETLCPP/etl

Copyright(c) 2014 jwellbelove

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/

#include <UnitTest++/UnitTest++.h>
#include "ExtraCheckMacros.h"

#include "data.h"

#include <set>
#include <vector>

#include "../pool.h"

typedef TestDataDC<std::string>  Test_Data;
typedef TestDataNDC<std::string> Test_Data2;

namespace
{
  SUITE(test_pool)
  {
    //*************************************************************************
    TEST(test_allocate)
    {
      etl::pool<Test_Data, 4> pool;

      Test_Data* p1;
      Test_Data* p2;
      Test_Data* p3;
      Test_Data* p4;

      CHECK_NO_THROW(p1 = pool.allocate());
      CHECK_NO_THROW(p2 = pool.allocate());
      CHECK_NO_THROW(p3 = pool.allocate());
      CHECK_NO_THROW(p4 = pool.allocate());

      CHECK(p1 != p2);
      CHECK(p1 != p3);
      CHECK(p1 != p4);
      CHECK(p2 != p3);
      CHECK(p2 != p4);
      CHECK(p3 != p4);

      CHECK_THROW(pool.allocate(), etl::pool_no_allocation);
    }

    //*************************************************************************
    TEST(test_release)
    {
      etl::pool<Test_Data, 4> pool;

      Test_Data* p1 = pool.allocate();
      Test_Data* p2 = pool.allocate();
      Test_Data* p3 = pool.allocate();
      Test_Data* p4 = pool.allocate();

      CHECK_NO_THROW(pool.release(p2));
      CHECK_NO_THROW(pool.release(*p3));
      CHECK_NO_THROW(pool.release(p1));
      CHECK_NO_THROW(pool.release(*p4));

      CHECK_EQUAL(4, pool.available());

      Test_Data not_in_pool;

      CHECK_THROW(pool.release(not_in_pool), etl::pool_object_not_in_pool);
    }

    //*************************************************************************
    TEST(test_allocate_release)
    {
      etl::pool<Test_Data, 4> pool;

      Test_Data* p1 = pool.allocate();
      Test_Data* p2 = pool.allocate();
      Test_Data* p3 = pool.allocate();
      Test_Data* p4 = pool.allocate();

      // Allocated p1, p2, p3, p4

      CHECK_EQUAL(0, pool.available());

      CHECK_NO_THROW(pool.release(p2));
      CHECK_NO_THROW(pool.release(p3));

      // Allocated p1, p4

      CHECK_EQUAL(2, pool.available());

      Test_Data* p5 = pool.allocate();
      Test_Data* p6 = pool.allocate();

      // Allocated p1, p4, p5, p6

      CHECK_EQUAL(0, pool.available());

      CHECK(p5 != p1);
      CHECK(p5 != p4);

      CHECK(p6 != p1);
      CHECK(p6 != p4);

      CHECK_NO_THROW(pool.release(p5));

      // Allocated p1, p4, p6

      CHECK_EQUAL(1, pool.available());

      Test_Data* p7 = pool.allocate();

      // Allocated p1, p4, p6, p7

      CHECK(p7 != p1);
      CHECK(p7 != p4);
      CHECK(p7 != p6);

      CHECK(pool.none_free());
    }

    //*************************************************************************
    TEST(test_available)
    {
      etl::pool<Test_Data, 4> pool;
      CHECK_EQUAL(4, pool.available());

      Test_Data* p;

      p = pool.allocate();
      CHECK_EQUAL(3, pool.available());

      p = pool.allocate();
      CHECK_EQUAL(2, pool.available());

      p = pool.allocate();
      CHECK_EQUAL(1, pool.available());

      p = pool.allocate();
      CHECK_EQUAL(0, pool.available());
    }

    //*************************************************************************
    TEST(test_none_free)
    {
      etl::pool<Test_Data, 4> pool;
      CHECK_EQUAL(4, pool.available());

      Test_Data* p;

      p = pool.allocate();
      CHECK(!pool.none_free());

      p = pool.allocate();
      CHECK(!pool.none_free());

      p = pool.allocate();
      CHECK(!pool.none_free());

      p = pool.allocate();
      CHECK(pool.none_free());
    }

    //*************************************************************************
    TEST(test_is_in_pool)
    {
      etl::pool<Test_Data, 4> pool;
      Test_Data not_in_pool;

      Test_Data* p1 = pool.allocate();

      CHECK(pool.is_in_pool(p1));
      CHECK(!pool.is_in_pool(not_in_pool));
    }

    //*************************************************************************
    TEST(test_const_iterator)
    {
      etl::pool<Test_Data2, 10> pool;

      std::set<Test_Data2>     compare = { Test_Data2("0"), Test_Data2("2"), Test_Data2("4"), Test_Data2("6"), Test_Data2("8") };
      std::set<Test_Data2>     test;
      std::vector<Test_Data2*> objects;

      // Build the set of objects.
      objects.push_back(pool.allocate(Test_Data2("9")));
      objects.push_back(pool.allocate(Test_Data2("7")));
      objects.push_back(pool.allocate(Test_Data2("8")));
      objects.push_back(pool.allocate(Test_Data2("6")));
      objects.push_back(pool.allocate(Test_Data2("5")));
      objects.push_back(pool.allocate(Test_Data2("3")));
      objects.push_back(pool.allocate(Test_Data2("4")));
      objects.push_back(pool.allocate(Test_Data2("2")));
      objects.push_back(pool.allocate(Test_Data2("0")));
      objects.push_back(pool.allocate(Test_Data2("1")));

      // Release "1", "3", "5", "7", "9".
      pool.release(objects[0]);
      pool.release(objects[1]);
      pool.release(objects[4]);
      pool.release(objects[5]);
      pool.release(objects[9]);

      // Fill the test set with what we get from the iterator.
      etl::pool<Test_Data2, 10>::const_iterator i_pool = pool.begin();

      while (i_pool != pool.end())
      {
        test.insert(*i_pool);
        ++i_pool;
      }

      // Compare the results.
      std::set<Test_Data2>::const_iterator i_compare = compare.begin();
      std::set<Test_Data2>::const_iterator i_test    = test.begin();

      CHECK_EQUAL(compare.size(), test.size());

      while ((i_compare != compare.end()) && (i_test != test.end()))
      {
        CHECK_EQUAL(*i_compare++, *i_test++);
      }
    }

    ////*************************************************************************
    //TEST(test_get_iterator)
    //{
    //  typedef etl::pool<Test_Data, 4> Pool;

    //  Pool pool;
    //  Test_Data not_in_pool;

    //  Test_Data* p1 = pool.allocate();
    //  Test_Data* p2 = pool.allocate();

    //  Pool::iterator i_data  = pool.get_iterator(*p1);
    //  Pool::iterator i_ndata = pool.get_iterator(not_in_pool);

    //  CHECK(p1 == &*i_data);
    //  CHECK(p2 != &*i_data);
    //  CHECK(pool.end() == i_ndata);
    //}

    ////*************************************************************************
    //TEST(test_get_iterator_const)
    //{
    //  typedef etl::pool<Test_Data, 4> Pool;

    //  Pool pool;
    //  const Test_Data not_in_pool;

    //  const Test_Data* p1 = pool.allocate();
    //  const Test_Data* p2 = pool.allocate();

    //  Pool::const_iterator i_data = pool.get_iterator(*p1);
    //  Pool::const_iterator i_ndata = pool.get_iterator(not_in_pool);

    //  CHECK(p1 == &*i_data);
    //  CHECK(p2 != &*i_data);
    //  CHECK(pool.end() == i_ndata);
    //}
  };
}
<|endoftext|>


<commit_before>/******************************************************************************
The MIT License(MIT)

Embedded Template Library.
https://github.com/ETLCPP/etl
http://www.etlcpp.com

Copyright(c) 2014 jwellbelove

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/

#include <UnitTest++/UnitTest++.h>
#include "ExtraCheckMacros.h"

#include "data.h"

#include <set>
#include <vector>

#include "../src/pool.h"

#if defined(ETL_COMPILER_GCC)
  #pragma GCC diagnostic push
  #pragma GCC diagnostic ignored "-Wunused-but-set-variable"
#endif

typedef TestDataDC<std::string>  Test_Data;
typedef TestDataNDC<std::string> Test_Data2;

namespace
{
  SUITE(test_pool)
  {
    //*************************************************************************
    TEST(test_allocate)
    {
      etl::pool<Test_Data, 4> pool;

      Test_Data* p1 = nullptr;
      Test_Data* p2 = nullptr;
      Test_Data* p3 = nullptr;
      Test_Data* p4 = nullptr;

      CHECK_NO_THROW(p1 = pool.allocate<Test_Data>());
      CHECK_NO_THROW(p2 = pool.allocate<Test_Data>());
      CHECK_NO_THROW(p3 = pool.allocate<Test_Data>());
      CHECK_NO_THROW(p4 = pool.allocate<Test_Data>());

      CHECK(p1 != p2);
      CHECK(p1 != p3);
      CHECK(p1 != p4);
      CHECK(p2 != p3);
      CHECK(p2 != p4);
      CHECK(p3 != p4);

      CHECK_THROW(pool.allocate<Test_Data>(), etl::pool_no_allocation);
    }

    //*************************************************************************
    TEST(test_release)
    {
      etl::pool<Test_Data, 4> pool;

      Test_Data* p1 = pool.allocate<Test_Data>();
      Test_Data* p2 = pool.allocate<Test_Data>();
      Test_Data* p3 = pool.allocate<Test_Data>();
      Test_Data* p4 = pool.allocate<Test_Data>();

      CHECK_NO_THROW(pool.release(p2));
      CHECK_NO_THROW(pool.release(p3));
      CHECK_NO_THROW(pool.release(p1));
      CHECK_NO_THROW(pool.release(p4));

      CHECK_EQUAL(4U, pool.available());

      Test_Data not_in_pool;

      CHECK_THROW(pool.release(&not_in_pool), etl::pool_object_not_in_pool);
    }

    //*************************************************************************
    TEST(test_allocate_release)
    {
      etl::pool<Test_Data, 4> pool;

      Test_Data* p1 = pool.allocate<Test_Data>();
      Test_Data* p2 = pool.allocate<Test_Data>();
      Test_Data* p3 = pool.allocate<Test_Data>();
      Test_Data* p4 = pool.allocate<Test_Data>();

      // Allocated p1, p2, p3, p4

      CHECK_EQUAL(0U, pool.available());

      CHECK_NO_THROW(pool.release(p2));
      CHECK_NO_THROW(pool.release(p3));

      // Allocated p1, p4

      CHECK_EQUAL(2U, pool.available());

      Test_Data* p5 = pool.allocate<Test_Data>();
      Test_Data* p6 = pool.allocate<Test_Data>();

      // Allocated p1, p4, p5, p6

      CHECK_EQUAL(0U, pool.available());

      CHECK(p5 != p1);
      CHECK(p5 != p4);

      CHECK(p6 != p1);
      CHECK(p6 != p4);

      CHECK_NO_THROW(pool.release(p5));

      // Allocated p1, p4, p6

      CHECK_EQUAL(1U, pool.available());

      Test_Data* p7 = pool.allocate<Test_Data>();

      // Allocated p1, p4, p6, p7

      CHECK(p7 != p1);
      CHECK(p7 != p4);
      CHECK(p7 != p6);

      CHECK(pool.full());
    }

    //*************************************************************************
    TEST(test_available)
    {
      etl::pool<Test_Data, 4> pool;
      CHECK_EQUAL(4U, pool.available());

      Test_Data* p;

      p = pool.allocate<Test_Data>();
      CHECK_EQUAL(3U, pool.available());

      p = pool.allocate<Test_Data>();
      CHECK_EQUAL(2U, pool.available());

      p = pool.allocate<Test_Data>();
      CHECK_EQUAL(1U, pool.available());

      p = pool.allocate<Test_Data>();
      CHECK_EQUAL(0U, pool.available());
    }

    //*************************************************************************
    TEST(test_max_size)
    {
      etl::pool<Test_Data, 4> pool;

      CHECK(pool.max_items() == 4U);
    }

    //*************************************************************************
    TEST(test_size)
    {
      etl::pool<Test_Data, 4> pool;
      CHECK_EQUAL(0U, pool.size());

      Test_Data* p;

      p = pool.allocate<Test_Data>();
      CHECK_EQUAL(1U, pool.size());

      p = pool.allocate<Test_Data>();
      CHECK_EQUAL(2U, pool.size());

      p = pool.allocate<Test_Data>();
      CHECK_EQUAL(3U, pool.size());

      p = pool.allocate<Test_Data>();
      CHECK_EQUAL(4U, pool.size());
    }

    //*************************************************************************
    TEST(test_empty_full)
    {
      etl::pool<Test_Data, 4> pool;
      CHECK(pool.empty());
      CHECK(!pool.full());

      Test_Data* p;

      p = pool.allocate<Test_Data>();
      CHECK(!pool.empty());
      CHECK(!pool.full());

      p = pool.allocate<Test_Data>();
      CHECK(!pool.empty());
      CHECK(!pool.full());

      p = pool.allocate<Test_Data>();
      CHECK(!pool.empty());
      CHECK(!pool.full());

      p = pool.allocate<Test_Data>();
      CHECK(!pool.empty());
      CHECK(pool.full());
    }

    //*************************************************************************
    TEST(test_is_in_pool)
    {
      etl::pool<Test_Data, 4> pool;
      Test_Data not_in_pool;

      Test_Data* p1 = pool.allocate<Test_Data>();

      CHECK(pool.is_in_pool(p1));
      CHECK(!pool.is_in_pool(&not_in_pool));
    }

    //*************************************************************************
    TEST(test_begin_empty)
    {
      //etl::pool<Test_Data, 4> pool;

      //etl::pool<Test_Data, 4>::iterator it = pool.begin();
      //CHECK(it == pool.end());

      //etl::pool<Test_Data, 4>::const_iterator cit = pool.begin();
      //CHECK(cit == pool.end());

      //cit = pool.cbegin();
      //CHECK(cit == pool.end());
    }

    //*************************************************************************
    TEST(test_iterator)
    {
      //etl::pool<Test_Data2, 10> pool;

      //std::set<Test_Data2>     compare = { Test_Data2("0"), Test_Data2("2"), Test_Data2("4"), Test_Data2("6"), Test_Data2("8") };
      //std::set<Test_Data2>     test;
      //std::vector<Test_Data2*> objects;

      //// Build the set of objects.
      //objects.push_back(pool.allocate(Test_Data2("9")));
      //objects.push_back(pool.allocate(Test_Data2("7")));
      //objects.push_back(pool.allocate(Test_Data2("8")));
      //objects.push_back(pool.allocate(Test_Data2("6")));
      //objects.push_back(pool.allocate(Test_Data2("5")));
      //objects.push_back(pool.allocate(Test_Data2("3")));
      //objects.push_back(pool.allocate(Test_Data2("4")));
      //objects.push_back(pool.allocate(Test_Data2("2")));
      //objects.push_back(pool.allocate(Test_Data2("0")));
      //objects.push_back(pool.allocate(Test_Data2("1")));

      //// Release "1", "3", "5", "7", "9".
      //pool.release(objects[0]);
      //pool.release(objects[1]);
      //pool.release(objects[4]);
      //pool.release(objects[5]);
      //pool.release(objects[9]);

      //// Fill the test set with what we get from the iterator.
      //etl::pool<Test_Data2, 10>::iterator i_pool = pool.begin();

      //while (i_pool != pool.end())
      //{
      //  test.insert(*i_pool);
      //  ++i_pool;
      //}

      //// Compare the results.
      //std::set<Test_Data2>::iterator i_compare = compare.begin();
      //std::set<Test_Data2>::iterator i_test = test.begin();

      //CHECK_EQUAL(compare.size(), test.size());

      //while ((i_compare != compare.end()) && (i_test != test.end()))
      //{
      //  CHECK_EQUAL(*i_compare++, *i_test++);
      //}
    }

    //*************************************************************************
    TEST(test_const_iterator)
    {
      //etl::pool<Test_Data2, 10> pool;

      //std::set<Test_Data2>     compare = { Test_Data2("0"), Test_Data2("2"), Test_Data2("4"), Test_Data2("6"), Test_Data2("8") };
      //std::set<Test_Data2>     test;
      //std::vector<Test_Data2*> objects;

      //// Build the set of objects.
      //objects.push_back(pool.allocate(Test_Data2("9")));
      //objects.push_back(pool.allocate(Test_Data2("7")));
      //objects.push_back(pool.allocate(Test_Data2("8")));
      //objects.push_back(pool.allocate(Test_Data2("6")));
      //objects.push_back(pool.allocate(Test_Data2("5")));
      //objects.push_back(pool.allocate(Test_Data2("3")));
      //objects.push_back(pool.allocate(Test_Data2("4")));
      //objects.push_back(pool.allocate(Test_Data2("2")));
      //objects.push_back(pool.allocate(Test_Data2("0")));
      //objects.push_back(pool.allocate(Test_Data2("1")));

      //// Release "1", "3", "5", "7", "9".
      //pool.release(objects[0]);
      //pool.release(objects[1]);
      //pool.release(objects[4]);
      //pool.release(objects[5]);
      //pool.release(objects[9]);

      //// Fill the test set with what we get from the iterator.
      //etl::pool<Test_Data2, 10>::const_iterator i_pool = pool.begin();

      //while (i_pool != pool.end())
      //{
      //  test.insert(*i_pool);
      //  ++i_pool;
      //}

      //// Compare the results.
      //std::set<Test_Data2>::const_iterator i_compare = compare.begin();
      //std::set<Test_Data2>::const_iterator i_test    = test.begin();

      //CHECK_EQUAL(compare.size(), test.size());

      //while ((i_compare != compare.end()) && (i_test != test.end()))
      //{
      //  CHECK_EQUAL(*i_compare++, *i_test++);
      //}
    }

    //*************************************************************************
    TEST(test_get_iterator)
    {
      //typedef etl::pool<Test_Data, 4> Pool;

      //Pool pool;
      //Test_Data not_in_pool;

      //Test_Data* p1 = pool.allocate<Test_Data>();
      //Test_Data* p2 = pool.allocate<Test_Data>();

      //Pool::iterator i_data  = pool.get_iterator(*p1);
      //Pool::iterator i_data2 = pool.get_iterator(*p2);
      //Pool::iterator i_ndata = pool.get_iterator(not_in_pool);

      //CHECK(p1 == &*i_data);
      //CHECK(p2 != &*i_data);
      //CHECK(p2 == &*i_data2);
      //CHECK(pool.end() == i_ndata);
    }

    //*************************************************************************
    TEST(test_get_iterator_const)
    {
      //typedef etl::pool<Test_Data, 4> Pool;

      //Pool pool;
      //const Test_Data not_in_pool;

      //const Test_Data* p1 = pool.allocate<Test_Data>();
      //const Test_Data* p2 = pool.allocate<Test_Data>();

      //Pool::const_iterator i_data  = pool.get_iterator(*p1);
      //Pool::const_iterator i_data2 = pool.get_iterator(*p2);
      //Pool::const_iterator i_ndata = pool.get_iterator(not_in_pool);

      //CHECK(p1 == &*i_data);
      //CHECK(p2 != &*i_data);
      //CHECK(p2 == &*i_data2);
      //CHECK(pool.end() == i_ndata);
    }
  };
}

#if defined(ETL_COMPILER_GCC)
  #pragma GCC diagnostic pop
#endif
<commit_msg>Removed redundant tests<commit_after>/******************************************************************************
The MIT License(MIT)

Embedded Template Library.
https://github.com/ETLCPP/etl
http://www.etlcpp.com

Copyright(c) 2014 jwellbelove

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/

#include <UnitTest++/UnitTest++.h>
#include "ExtraCheckMacros.h"

#include "data.h"

#include <set>
#include <vector>

#include "../src/pool.h"

#if defined(ETL_COMPILER_GCC)
  #pragma GCC diagnostic push
  #pragma GCC diagnostic ignored "-Wunused-but-set-variable"
#endif

typedef TestDataDC<std::string>  Test_Data;
typedef TestDataNDC<std::string> Test_Data2;

namespace
{
  SUITE(test_pool)
  {
    //*************************************************************************
    TEST(test_allocate)
    {
      etl::pool<Test_Data, 4> pool;

      Test_Data* p1 = nullptr;
      Test_Data* p2 = nullptr;
      Test_Data* p3 = nullptr;
      Test_Data* p4 = nullptr;

      CHECK_NO_THROW(p1 = pool.allocate<Test_Data>());
      CHECK_NO_THROW(p2 = pool.allocate<Test_Data>());
      CHECK_NO_THROW(p3 = pool.allocate<Test_Data>());
      CHECK_NO_THROW(p4 = pool.allocate<Test_Data>());

      CHECK(p1 != p2);
      CHECK(p1 != p3);
      CHECK(p1 != p4);
      CHECK(p2 != p3);
      CHECK(p2 != p4);
      CHECK(p3 != p4);

      CHECK_THROW(pool.allocate<Test_Data>(), etl::pool_no_allocation);
    }

    //*************************************************************************
    TEST(test_release)
    {
      etl::pool<Test_Data, 4> pool;

      Test_Data* p1 = pool.allocate<Test_Data>();
      Test_Data* p2 = pool.allocate<Test_Data>();
      Test_Data* p3 = pool.allocate<Test_Data>();
      Test_Data* p4 = pool.allocate<Test_Data>();

      CHECK_NO_THROW(pool.release(p2));
      CHECK_NO_THROW(pool.release(p3));
      CHECK_NO_THROW(pool.release(p1));
      CHECK_NO_THROW(pool.release(p4));

      CHECK_EQUAL(4U, pool.available());

      Test_Data not_in_pool;

      CHECK_THROW(pool.release(&not_in_pool), etl::pool_object_not_in_pool);
    }

    //*************************************************************************
    TEST(test_allocate_release)
    {
      etl::pool<Test_Data, 4> pool;

      Test_Data* p1 = pool.allocate<Test_Data>();
      Test_Data* p2 = pool.allocate<Test_Data>();
      Test_Data* p3 = pool.allocate<Test_Data>();
      Test_Data* p4 = pool.allocate<Test_Data>();

      // Allocated p1, p2, p3, p4

      CHECK_EQUAL(0U, pool.available());

      CHECK_NO_THROW(pool.release(p2));
      CHECK_NO_THROW(pool.release(p3));

      // Allocated p1, p4

      CHECK_EQUAL(2U, pool.available());

      Test_Data* p5 = pool.allocate<Test_Data>();
      Test_Data* p6 = pool.allocate<Test_Data>();

      // Allocated p1, p4, p5, p6

      CHECK_EQUAL(0U, pool.available());

      CHECK(p5 != p1);
      CHECK(p5 != p4);

      CHECK(p6 != p1);
      CHECK(p6 != p4);

      CHECK_NO_THROW(pool.release(p5));

      // Allocated p1, p4, p6

      CHECK_EQUAL(1U, pool.available());

      Test_Data* p7 = pool.allocate<Test_Data>();

      // Allocated p1, p4, p6, p7

      CHECK(p7 != p1);
      CHECK(p7 != p4);
      CHECK(p7 != p6);

      CHECK(pool.full());
    }

    //*************************************************************************
    TEST(test_available)
    {
      etl::pool<Test_Data, 4> pool;
      CHECK_EQUAL(4U, pool.available());

      Test_Data* p;

      p = pool.allocate<Test_Data>();
      CHECK_EQUAL(3U, pool.available());

      p = pool.allocate<Test_Data>();
      CHECK_EQUAL(2U, pool.available());

      p = pool.allocate<Test_Data>();
      CHECK_EQUAL(1U, pool.available());

      p = pool.allocate<Test_Data>();
      CHECK_EQUAL(0U, pool.available());
    }

    //*************************************************************************
    TEST(test_max_size)
    {
      etl::pool<Test_Data, 4> pool;

      CHECK(pool.max_items() == 4U);
    }

    //*************************************************************************
    TEST(test_size)
    {
      etl::pool<Test_Data, 4> pool;
      CHECK_EQUAL(0U, pool.size());

      Test_Data* p;

      p = pool.allocate<Test_Data>();
      CHECK_EQUAL(1U, pool.size());

      p = pool.allocate<Test_Data>();
      CHECK_EQUAL(2U, pool.size());

      p = pool.allocate<Test_Data>();
      CHECK_EQUAL(3U, pool.size());

      p = pool.allocate<Test_Data>();
      CHECK_EQUAL(4U, pool.size());
    }

    //*************************************************************************
    TEST(test_empty_full)
    {
      etl::pool<Test_Data, 4> pool;
      CHECK(pool.empty());
      CHECK(!pool.full());

      Test_Data* p;

      p = pool.allocate<Test_Data>();
      CHECK(!pool.empty());
      CHECK(!pool.full());

      p = pool.allocate<Test_Data>();
      CHECK(!pool.empty());
      CHECK(!pool.full());

      p = pool.allocate<Test_Data>();
      CHECK(!pool.empty());
      CHECK(!pool.full());

      p = pool.allocate<Test_Data>();
      CHECK(!pool.empty());
      CHECK(pool.full());
    }

    //*************************************************************************
    TEST(test_is_in_pool)
    {
      etl::pool<Test_Data, 4> pool;
      Test_Data not_in_pool;

      Test_Data* p1 = pool.allocate<Test_Data>();

      CHECK(pool.is_in_pool(p1));
      CHECK(!pool.is_in_pool(&not_in_pool));
    }
  };
}

#if defined(ETL_COMPILER_GCC)
  #pragma GCC diagnostic pop
#endif
<|endoftext|>


<commit_before>#include <fstream>
#include <string>

#include <cxxtest/TestSuite.h>

#include "linkedqueue/Queue.h"
#include "parser.h"
#include "resyntax/resyntax.h"

class MyTestSuite : public CxxTest::TestSuite {
  public:
    void test1() {
      linkedqueue::Queue<int> q;
      if (q.is_empty()) {
        q.enqueue(3);
        q.enqueue(4);
        q.enqueue(5);
      }
      TS_ASSERT_EQUALS(q.size(), 3);
      if (!q.is_empty()) {
        int a = q.pop();
        q.enqueue(a);
      }
      TS_ASSERT_EQUALS(q.pop(), 4);
      TS_ASSERT_EQUALS(q.peek(), 5);
      TS_ASSERT_EQUALS(q.size(), 2);
      TS_ASSERT_EQUALS(q.is_empty(), false);
    }

    void test2() {
      std::string regexp = "(a|b)*c";
      tinygrep::resyntax::RegExp ast = tinygrep::parse(regexp);
      TS_ASSERT_EQUALS(ast.getType(), tinygrep::resyntax::RegExpEnum::kConcatenation);
      tinygrep::resyntax::RegExp a_or_b_star = ast.getR1();
      tinygrep::resyntax::RegExp c = ast.getR2();
      TS_ASSERT_EQUALS(a_or_b_star.getR1().getR2().getType(), tinygrep::resyntax::RegExpEnum::kLiteral);
    }

    void test3() {
      std::string regexp = "(a|b)*c";
      tinygrep::resyntax::RegExp ast = tinygrep::parse(regexp);
      std::string regexp_test_graph = tinygrep::resyntax::to_graph(ast);
      std::ofstream os("build/test3_graph.gv");
      if (os.is_open()) {
        os << regexp_test_graph;
      }
    }
};
<commit_msg>Add test for epsilon-NFA creation and matching.<commit_after>#include <fstream>
#include <string>

#include <cxxtest/TestSuite.h>

#include "linkedqueue/Queue.h"
#include "enfa.h"
#include "parser.h"
#include "resyntax/resyntax.h"

class MyTestSuite : public CxxTest::TestSuite {
  public:
    void test1() {
      linkedqueue::Queue<int> q;
      if (q.is_empty()) {
        q.enqueue(3);
        q.enqueue(4);
        q.enqueue(5);
      }
      TS_ASSERT_EQUALS(q.size(), 3);
      if (!q.is_empty()) {
        int a = q.pop();
        q.enqueue(a);
      }
      TS_ASSERT_EQUALS(q.pop(), 4);
      TS_ASSERT_EQUALS(q.peek(), 5);
      TS_ASSERT_EQUALS(q.size(), 2);
      TS_ASSERT_EQUALS(q.is_empty(), false);
    }

    void test2() {
      std::string regexp = "(a|b)*c";
      // Parse a string to a RegExp AST.
      tinygrep::resyntax::RegExp ast = tinygrep::parse(regexp);
      TS_ASSERT_EQUALS(ast.getType(), tinygrep::resyntax::RegExpEnum::kConcatenation);
      tinygrep::resyntax::RegExp a_or_b_star = ast.getR1();
      tinygrep::resyntax::RegExp c = ast.getR2();
      TS_ASSERT_EQUALS(a_or_b_star.getR1().getR2().getType(), tinygrep::resyntax::RegExpEnum::kLiteral);
      // Create a graph representation.
      std::string regexp_test_graph = tinygrep::resyntax::to_graph(ast);
      std::ofstream os_regexp("build/test_regexp_graph.gv");
      if (os_regexp.is_open()) {
        os_regexp << regexp_test_graph;
      }
      // Generate EpsilonNFA from AST.
      tinygrep::enfa::EpsilonNFA enfautomaton = tinygrep::enfa::EpsilonNFA(ast);
      TS_ASSERT(enfautomaton.accepts("abbaaababc"));
      TS_ASSERT(enfautomaton.accepts("abc"));
      TS_ASSERT(enfautomaton.accepts("bac"));
      TS_ASSERT(enfautomaton.accepts("c"));
      TS_ASSERT(!enfautomaton.accepts("cc"));
      TS_ASSERT(!enfautomaton.accepts("abbaabababab"));
      TS_ASSERT(!enfautomaton.accepts("acc"));
      TS_ASSERT(!enfautomaton.accepts(""));
    }

};
<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/gfx/gtk_preserve_window.h"

#include <gdk/gdkwindow.h>
#include <gtk/gtk.h>
#include <gtk/gtkwidget.h>
#include <gtk/gtkfixed.h>

G_BEGIN_DECLS

#define GTK_PRESERVE_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
                                            GTK_TYPE_PRESERVE_WINDOW, \
                                            GtkPreserveWindowPrivate))

typedef struct _GtkPreserveWindowPrivate GtkPreserveWindowPrivate;

struct _GtkPreserveWindowPrivate {
  // If true, don't create/destroy windows on realize/unrealize.
  gboolean preserve_window;

  // Whether or not we delegate the resize of the GdkWindow
  // to someone else.
  gboolean delegate_resize;
};

G_DEFINE_TYPE(GtkPreserveWindow, gtk_preserve_window, GTK_TYPE_FIXED)

static void gtk_preserve_window_destroy(GtkObject* object);
static void gtk_preserve_window_realize(GtkWidget* widget);
static void gtk_preserve_window_unrealize(GtkWidget* widget);
static void gtk_preserve_window_size_allocate(GtkWidget* widget,
                                              GtkAllocation* allocation);

static void gtk_preserve_window_class_init(GtkPreserveWindowClass *klass) {
  GtkWidgetClass* widget_class = reinterpret_cast<GtkWidgetClass*>(klass);
  widget_class->realize = gtk_preserve_window_realize;
  widget_class->unrealize = gtk_preserve_window_unrealize;
  widget_class->size_allocate = gtk_preserve_window_size_allocate;

  GtkObjectClass* object_class = reinterpret_cast<GtkObjectClass*>(klass);
  object_class->destroy = gtk_preserve_window_destroy;

  GObjectClass* gobject_class = G_OBJECT_CLASS(klass);
  g_type_class_add_private(gobject_class, sizeof(GtkPreserveWindowPrivate));
}

static void gtk_preserve_window_init(GtkPreserveWindow* widget) {
  GtkPreserveWindowPrivate* priv = GTK_PRESERVE_WINDOW_GET_PRIVATE(widget);
  priv->preserve_window = FALSE;

  // These widgets always have their own window.
  gtk_fixed_set_has_window(GTK_FIXED(widget), TRUE);
}

GtkWidget* gtk_preserve_window_new() {
  return GTK_WIDGET(g_object_new(GTK_TYPE_PRESERVE_WINDOW, NULL));
}

static void gtk_preserve_window_destroy(GtkObject* object) {
  GtkWidget* widget = reinterpret_cast<GtkWidget*>(object);
  GtkPreserveWindowPrivate* priv = GTK_PRESERVE_WINDOW_GET_PRIVATE(widget);

  if (widget->window) {
    gdk_window_set_user_data(widget->window, NULL);
    // If the window is preserved, someone else must destroy it.
    if (!priv->preserve_window)
      gdk_window_destroy(widget->window);
    widget->window = NULL;
  }

  GTK_OBJECT_CLASS(gtk_preserve_window_parent_class)->destroy(object);
}

static void gtk_preserve_window_realize(GtkWidget* widget) {
  g_return_if_fail(GTK_IS_PRESERVE_WINDOW(widget));

  if (widget->window) {
    gdk_window_reparent(widget->window,
                        gtk_widget_get_parent_window(widget),
                        widget->allocation.x,
                        widget->allocation.y);
    widget->style = gtk_style_attach(widget->style, widget->window);
    gtk_style_set_background(widget->style, widget->window, GTK_STATE_NORMAL);

    gint event_mask = gtk_widget_get_events(widget);
    event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK;
    gdk_window_set_events(widget->window, (GdkEventMask) event_mask);
    gdk_window_set_user_data(widget->window, widget);

    // Deprecated as of GTK 2.22. Used for compatibility.
    // It should be: gtk_widget_set_realized(widget, TRUE)
    GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
  } else {
    GTK_WIDGET_CLASS(gtk_preserve_window_parent_class)->realize(widget);
  }
}

static void gtk_preserve_window_unrealize(GtkWidget* widget) {
  g_return_if_fail(GTK_IS_PRESERVE_WINDOW(widget));

  GtkPreserveWindowPrivate* priv = GTK_PRESERVE_WINDOW_GET_PRIVATE(widget);
  if (priv->preserve_window) {
    GtkWidgetClass* widget_class =
        GTK_WIDGET_CLASS(gtk_preserve_window_parent_class);
    GtkContainerClass* container_class =
        GTK_CONTAINER_CLASS(gtk_preserve_window_parent_class);

    // Deprecated as of GTK 2.22. Used for compatibility.
    // It should be: gtk_widget_get_mapped()
    if (GTK_WIDGET_MAPPED(widget)) {
      widget_class->unmap(widget);

      // Deprecated as of GTK 2.22. Used for compatibility.
      // It should be: gtk_widget_set_mapped(widget, FALSE)
      GTK_WIDGET_UNSET_FLAGS(widget, GTK_MAPPED);
    }

    // This is the behavior from GtkWidget, inherited by GtkFixed.
    // It is unclear why we should not call the potentially overridden
    // unrealize method (via the callback), but doing so causes errors.
    container_class->forall(
        GTK_CONTAINER(widget), FALSE,
        reinterpret_cast<GtkCallback>(gtk_widget_unrealize), NULL);

    gtk_style_detach(widget->style);
    gdk_window_reparent(widget->window, gdk_get_default_root_window(), 0, 0);
    gtk_selection_remove_all(widget);
    gdk_window_set_user_data(widget->window, NULL);

    // Deprecated as of GTK 2.22. Used for compatibility.
    // It should be: gtk_widget_set_realized(widget, FALSE)
    GTK_WIDGET_UNSET_FLAGS(widget, GTK_REALIZED);
  } else {
    GTK_WIDGET_CLASS(gtk_preserve_window_parent_class)->unrealize(widget);
  }
}

gboolean gtk_preserve_window_get_preserve(GtkPreserveWindow* window) {
  g_return_val_if_fail(GTK_IS_PRESERVE_WINDOW(window), FALSE);
  GtkPreserveWindowPrivate* priv = GTK_PRESERVE_WINDOW_GET_PRIVATE(window);

  return priv->preserve_window;
}

void gtk_preserve_window_set_preserve(GtkPreserveWindow* window,
                                      gboolean value) {
  g_return_if_fail(GTK_IS_PRESERVE_WINDOW(window));
  GtkPreserveWindowPrivate* priv = GTK_PRESERVE_WINDOW_GET_PRIVATE(window);
  priv->preserve_window = value;

  GtkWidget* widget = GTK_WIDGET(window);
  if (value && !widget->window) {
    GdkWindowAttr attributes;
    gint attributes_mask;

    // We may not know the width and height, so we rely on the fact
    // that a size-allocation will resize it later.
    attributes.width = 1;
    attributes.height = 1;

    attributes.window_type = GDK_WINDOW_CHILD;
    attributes.wclass = GDK_INPUT_OUTPUT;

    attributes.visual = gtk_widget_get_visual(widget);
    attributes.colormap = gtk_widget_get_colormap(widget);

    attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP;
    widget->window = gdk_window_new(
        gdk_get_default_root_window(), &attributes, attributes_mask);
  } else if (!value && widget->window && !GTK_WIDGET_REALIZED(widget)) {
    gdk_window_destroy(widget->window);
    widget->window = NULL;
  }
}

void gtk_preserve_window_size_allocate(GtkWidget* widget,
                                       GtkAllocation* allocation) {
  g_return_if_fail(GTK_IS_PRESERVE_WINDOW(widget));
  GtkPreserveWindowPrivate* priv = GTK_PRESERVE_WINDOW_GET_PRIVATE(widget);

  if (priv->delegate_resize) {
    // Just update the state. Someone else will gdk_window_resize the
    // associated GdkWindow.
    widget->allocation = *allocation;
  } else {
    GTK_WIDGET_CLASS(gtk_preserve_window_parent_class)->size_allocate(
        widget, allocation);
  }
}

void gtk_preserve_window_delegate_resize(GtkPreserveWindow* widget,
                                         gboolean delegate) {
  GtkPreserveWindowPrivate* priv = GTK_PRESERVE_WINDOW_GET_PRIVATE(widget);
  priv->delegate_resize = delegate;
}

G_END_DECLS
<commit_msg>To prevent damage to the back-buffer, it's only necessary to defer resize.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/gfx/gtk_preserve_window.h"

#include <gdk/gdkwindow.h>
#include <gtk/gtk.h>
#include <gtk/gtkwidget.h>
#include <gtk/gtkfixed.h>

G_BEGIN_DECLS

#define GTK_PRESERVE_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
                                            GTK_TYPE_PRESERVE_WINDOW, \
                                            GtkPreserveWindowPrivate))

typedef struct _GtkPreserveWindowPrivate GtkPreserveWindowPrivate;

struct _GtkPreserveWindowPrivate {
  // If true, don't create/destroy windows on realize/unrealize.
  gboolean preserve_window;

  // Whether or not we delegate the resize of the GdkWindow
  // to someone else.
  gboolean delegate_resize;
};

G_DEFINE_TYPE(GtkPreserveWindow, gtk_preserve_window, GTK_TYPE_FIXED)

static void gtk_preserve_window_destroy(GtkObject* object);
static void gtk_preserve_window_realize(GtkWidget* widget);
static void gtk_preserve_window_unrealize(GtkWidget* widget);
static void gtk_preserve_window_size_allocate(GtkWidget* widget,
                                              GtkAllocation* allocation);

static void gtk_preserve_window_class_init(GtkPreserveWindowClass *klass) {
  GtkWidgetClass* widget_class = reinterpret_cast<GtkWidgetClass*>(klass);
  widget_class->realize = gtk_preserve_window_realize;
  widget_class->unrealize = gtk_preserve_window_unrealize;
  widget_class->size_allocate = gtk_preserve_window_size_allocate;

  GtkObjectClass* object_class = reinterpret_cast<GtkObjectClass*>(klass);
  object_class->destroy = gtk_preserve_window_destroy;

  GObjectClass* gobject_class = G_OBJECT_CLASS(klass);
  g_type_class_add_private(gobject_class, sizeof(GtkPreserveWindowPrivate));
}

static void gtk_preserve_window_init(GtkPreserveWindow* widget) {
  GtkPreserveWindowPrivate* priv = GTK_PRESERVE_WINDOW_GET_PRIVATE(widget);
  priv->preserve_window = FALSE;

  // These widgets always have their own window.
  gtk_fixed_set_has_window(GTK_FIXED(widget), TRUE);
}

GtkWidget* gtk_preserve_window_new() {
  return GTK_WIDGET(g_object_new(GTK_TYPE_PRESERVE_WINDOW, NULL));
}

static void gtk_preserve_window_destroy(GtkObject* object) {
  GtkWidget* widget = reinterpret_cast<GtkWidget*>(object);
  GtkPreserveWindowPrivate* priv = GTK_PRESERVE_WINDOW_GET_PRIVATE(widget);

  if (widget->window) {
    gdk_window_set_user_data(widget->window, NULL);
    // If the window is preserved, someone else must destroy it.
    if (!priv->preserve_window)
      gdk_window_destroy(widget->window);
    widget->window = NULL;
  }

  GTK_OBJECT_CLASS(gtk_preserve_window_parent_class)->destroy(object);
}

static void gtk_preserve_window_realize(GtkWidget* widget) {
  g_return_if_fail(GTK_IS_PRESERVE_WINDOW(widget));

  if (widget->window) {
    gdk_window_reparent(widget->window,
                        gtk_widget_get_parent_window(widget),
                        widget->allocation.x,
                        widget->allocation.y);
    widget->style = gtk_style_attach(widget->style, widget->window);
    gtk_style_set_background(widget->style, widget->window, GTK_STATE_NORMAL);

    gint event_mask = gtk_widget_get_events(widget);
    event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK;
    gdk_window_set_events(widget->window, (GdkEventMask) event_mask);
    gdk_window_set_user_data(widget->window, widget);

    // Deprecated as of GTK 2.22. Used for compatibility.
    // It should be: gtk_widget_set_realized(widget, TRUE)
    GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
  } else {
    GTK_WIDGET_CLASS(gtk_preserve_window_parent_class)->realize(widget);
  }
}

static void gtk_preserve_window_unrealize(GtkWidget* widget) {
  g_return_if_fail(GTK_IS_PRESERVE_WINDOW(widget));

  GtkPreserveWindowPrivate* priv = GTK_PRESERVE_WINDOW_GET_PRIVATE(widget);
  if (priv->preserve_window) {
    GtkWidgetClass* widget_class =
        GTK_WIDGET_CLASS(gtk_preserve_window_parent_class);
    GtkContainerClass* container_class =
        GTK_CONTAINER_CLASS(gtk_preserve_window_parent_class);

    // Deprecated as of GTK 2.22. Used for compatibility.
    // It should be: gtk_widget_get_mapped()
    if (GTK_WIDGET_MAPPED(widget)) {
      widget_class->unmap(widget);

      // Deprecated as of GTK 2.22. Used for compatibility.
      // It should be: gtk_widget_set_mapped(widget, FALSE)
      GTK_WIDGET_UNSET_FLAGS(widget, GTK_MAPPED);
    }

    // This is the behavior from GtkWidget, inherited by GtkFixed.
    // It is unclear why we should not call the potentially overridden
    // unrealize method (via the callback), but doing so causes errors.
    container_class->forall(
        GTK_CONTAINER(widget), FALSE,
        reinterpret_cast<GtkCallback>(gtk_widget_unrealize), NULL);

    gtk_style_detach(widget->style);
    gdk_window_reparent(widget->window, gdk_get_default_root_window(), 0, 0);
    gtk_selection_remove_all(widget);
    gdk_window_set_user_data(widget->window, NULL);

    // Deprecated as of GTK 2.22. Used for compatibility.
    // It should be: gtk_widget_set_realized(widget, FALSE)
    GTK_WIDGET_UNSET_FLAGS(widget, GTK_REALIZED);
  } else {
    GTK_WIDGET_CLASS(gtk_preserve_window_parent_class)->unrealize(widget);
  }
}

gboolean gtk_preserve_window_get_preserve(GtkPreserveWindow* window) {
  g_return_val_if_fail(GTK_IS_PRESERVE_WINDOW(window), FALSE);
  GtkPreserveWindowPrivate* priv = GTK_PRESERVE_WINDOW_GET_PRIVATE(window);

  return priv->preserve_window;
}

void gtk_preserve_window_set_preserve(GtkPreserveWindow* window,
                                      gboolean value) {
  g_return_if_fail(GTK_IS_PRESERVE_WINDOW(window));
  GtkPreserveWindowPrivate* priv = GTK_PRESERVE_WINDOW_GET_PRIVATE(window);
  priv->preserve_window = value;

  GtkWidget* widget = GTK_WIDGET(window);
  if (value && !widget->window) {
    GdkWindowAttr attributes;
    gint attributes_mask;

    // We may not know the width and height, so we rely on the fact
    // that a size-allocation will resize it later.
    attributes.width = 1;
    attributes.height = 1;

    attributes.window_type = GDK_WINDOW_CHILD;
    attributes.wclass = GDK_INPUT_OUTPUT;

    attributes.visual = gtk_widget_get_visual(widget);
    attributes.colormap = gtk_widget_get_colormap(widget);

    attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP;
    widget->window = gdk_window_new(
        gdk_get_default_root_window(), &attributes, attributes_mask);
  } else if (!value && widget->window && !GTK_WIDGET_REALIZED(widget)) {
    gdk_window_destroy(widget->window);
    widget->window = NULL;
  }
}

void gtk_preserve_window_size_allocate(GtkWidget* widget,
                                       GtkAllocation* allocation) {
  g_return_if_fail(GTK_IS_PRESERVE_WINDOW(widget));
  GtkPreserveWindowPrivate* priv = GTK_PRESERVE_WINDOW_GET_PRIVATE(widget);

  if (priv->delegate_resize) {
    widget->allocation = *allocation;
    // Only update the position. Someone else will call gdk_window_resize.
    if (GTK_WIDGET_REALIZED(widget)) {
      gdk_window_move(widget->window, allocation->x, allocation->y);
    }
  } else {
    GTK_WIDGET_CLASS(gtk_preserve_window_parent_class)->size_allocate(
        widget, allocation);
  }
}

void gtk_preserve_window_delegate_resize(GtkPreserveWindow* widget,
                                         gboolean delegate) {
  GtkPreserveWindowPrivate* priv = GTK_PRESERVE_WINDOW_GET_PRIVATE(widget);
  priv->delegate_resize = delegate;
}

G_END_DECLS
<|endoftext|>