/*
   HARK Library
   Copyright (C) 2021 Honda Research Institute Japan Inc.
 */

#if !defined(_HARKLIB_INTERNAL_CONDITION_VARIABLE_H_INCLUDED_)
#define _HARKLIB_INTERNAL_CONDITION_VARIABLE_H_INCLUDED_ 1

#include "hark-lib/object.h"

// #include "hark-lib/internal/lock.h"
#include <functional>

#if defined(__cplusplus_cli)
namespace std
{
    class condition_variable;
}
#else
#include <condition_variable>
#endif

namespace hark
{
    class UniqueLock;

    class ConditionVariableBaseImpl: public object
    {
    public:
        virtual void wait(UniqueLock &lock) = 0;
        virtual void wait(UniqueLock &lock, std::function<bool()> pred) = 0;
        virtual void notify_one() = 0;
    };

    class ConditionVariable: public object
    {
    public:
        ConditionVariable();
        ~ConditionVariable() = default;

        ConditionVariable(const ConditionVariable &) = delete;
        ConditionVariable(ConditionVariable &&) = delete;

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

    public:
        void wait(UniqueLock& lock);
        void wait(UniqueLock &lock, std::function<bool()> pred);
        void notify_one();

    private:
        std::unique_ptr<std::condition_variable> _impl;
    };

}

#endif /* #if !defined(_HARKLIB_INTERNAL_CONDITION_VARIABLE_H_INCLUDED_) */

/* end of file */
