я должен сделать функции-члены, которые работают с регулируемыми часами статическими?

У меня есть следующие два заголовка.

#ifndef DRD_EVENT_HPP
#define DRD_EVENT_HPP

#include <functional>

namespace drd
{

template <typename Clock>
class event
{
public:

using clock = Clock;
using time_point = typename clock::time_point;

template <class F, class... Args>
event(time_point et, F&& f, Args&&... args) :
Task(std::bind<void>(std::forward<F>(f), std::forward<Args>(args)...)),
Time(et) {}

void perform() ///Can throw std::bad_function_call
{
Task();
Task = nullptr;
}

///Returns the event time.
time_point time() const noexcept
{ return Time; }

///Checks if the event has not been performed yet.
bool pending() const noexcept
{ return static_cast<bool>(Task); }

private:

std::function< void()> Task;
time_point Time;
};

struct later_event
{
template <class Clock>
bool operator()(const event<Clock>& lhs, const event<Clock>& rhs)
const noexcept
{
return lhs.time() > rhs.time();
}
};

}

#endif // DRD_EVENT_HPP#ifndef DRD_DISCRETE_SIMULATION_HPP
#define DRD_DISCRETE_SIMULATION_HPP

#include <exception>
#include <chrono>
#include <queue>
#include "event.hpp"
namespace drd
{
namespace des ///Discrete event simulation
{

template <class Rep, class Period = std::ratio<1>>
class simulation_engine
{
public:

class clock;
using time_point = typename clock::time_point;
using duration = typename clock::duration;
using event_type = event<clock>;

public:///Constructs an event "in-place" and inserts it in the events list
template <typename... EventArgs>
void schedule(EventArgs&&... event_args_)
{
EventsList.emplace(std::forward<EventArgs>(event_args_)...);
}

bool has_pending_events() const noexcept
{ return not EventsList.empty(); }///Advances the clock until the next event time and then the event
///is performed, if the events list was empty the behavior is undefined.
void next_event()
{
auto Event = EventsList.top();
EventsList.pop();
clock::advance_until(Event.time());
Event.perform();
}

///Calls next_event() while the events list is not empty.
void simulate()
{ while (has_pending_events()) next_event();}///Performs all of events whose time is scheduled before or just at the
///moment t, then advances the clock until t.

void simulate_until(time_point t)
{
while(has_pending_events() and EventsList.top().time() <= t)
next_event();
clock::advance_until(t);
}

void simulate_for(duration d)
{  simulate_until(clock::now() + d); }private:

std::priority_queue<event_type, std::vector<event_type>,
later_event> EventsList;
};///clock type that is thread-independent and adjustable by
///simulation_engine

template <class Rep, class Period>
class simulation_engine<Rep,Period>::clock
{
public:

using rep = Rep;
using period = Period;
using duration = std::chrono::duration<rep,period>;
using time_point = std::chrono::time_point<clock>;

public:

static constexpr bool is_steady = false;

public:

static time_point now() noexcept
{ return CurrentTime;}

private:

static void reset() noexcept
{ CurrentTime = time_point(); }

static void adjust(time_point t) noexcept
{ CurrentTime = t; }

static void advance_until(time_point t)
{
if(t < CurrentTime)
throw std::logic_error("advance_until cannot set the clock back.");
CurrentTime = t;
}

friend simulation_engine<Rep,Period>;

private:

static thread_local time_point CurrentTime;
};

template <class Rep, class Period>
thread_local typename simulation_engine<Rep,Period>::clock::time_point
simulation_engine<Rep,Period>::clock::CurrentTime;}
}

#endif //DRD_DISCRETE_SIMULATION_HPP

Мне было интересно, должен ли я сделать функции-члены Simulation_engine статическими, потому что объекты владеют независимым списком событий и используют одни и те же часы и могут возникнуть проблемы с синхронизацией.

Что я должен делать?

Извините за мой английский и обширный код.
Я надеюсь, что ваш ответ, заранее спасибо.

3

Решение

Я наконец решил сделать это, я думаю, что это гораздо безопаснее и полезнее

  struct bad_event_scheduling : std::logic_error
{
bad_event_scheduling() :
std::logic_error("bad_event_scheduling") {}
};

template <class Clock>
class simulator
{
public:

using clock = Clock;
using time_point = typename clock::time_point;
using duration = typename clock::duration;
using event_type = event<clock>;

private:

using calendar_type = std::priority_queue<event_type,
std::vector<event_type>, later_event>;

public:

void reset()
{
CurrentTime = time_point();
EventsList = calendar_type();
}

time_point current_time() const noexcept
{
return CurrentTime;
}

///Constructs an event "in-place" and inserts it in the events list
template <typename... OtherArgs>
void schedule(const time_point& et, OtherArgs&&... other_args_)
{
if(et < CurrentTime) throw bad_event_scheduling();
EventsList.emplace(et, std::forward<OtherArgs>(other_args_)...);
}

bool has_pending_events() const noexcept
{ return not EventsList.empty(); }///Advances the clock until the next event time and then the event
///is performed, if the events list was empty the behavior is undefined.
void next_event()
{
auto Event = EventsList.top();
EventsList.pop();
CurrentTime = Event.time();
Event.perform();
}

///Calls next_event() while the events list is not empty.
void simulate()
{ while (has_pending_events()) next_event();}///if t >= current_time(), performs all of events whose time is scheduled
///before or just at the moment t, and then advances the current time until t.

void simulate_until(const time_point& t)
{
if( t >= CurrentTime)
{
while(has_pending_events() and EventsList.top().time() <= t)
next_event();
CurrentTime = t;
}
}

void simulate_for(const duration& d)
{  simulate_until(CurrentTime + d); }

private:

calendar_type EventsList;
time_point CurrentTime;
};
1

Другие решения

Если вы все переменные собираетесь быть статическими, то имеет смысл иметь статические функции-члены. Однако если нет, то у вас не должно быть всех статических функций. Если вы хотите, чтобы он был потокобезопасным, вам следует также заблокировать все функции. Я думаю, что вы также можете реализовать шаблон проектирования Singleton.http://en.wikipedia.org/wiki/Singleton_pattern

0

По вопросам рекламы [email protected]