c++ - should I make member functions that work with an adjustable clock static? -


i have following 2 headers.

#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 event time.       time_point time() const noexcept       { return time; }        ///checks if 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 event "in-place" , inserts in 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 clock until next event time , event       ///is performed, if events list empty behavior undefined.       void next_event()       {          auto event = eventslist.top();          eventslist.pop();          clock::advance_until(event.time());          event.perform();       }        ///calls next_event() while events list not empty.       void simulate()       { while (has_pending_events()) next_event();}         ///performs of events time scheduled before or @       ///moment t, advances clock until t.        void simulate_until(time_point t)       {         while(has_pending_events() , 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 thread-independent , adjustable  ///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 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 

i wondering if should make member functions of simulation_engine static, because objects own independent events list , share same clock, , might happen synchronization problem.

what should do?

sorry english , extensive code. hope answer, thank in advance.

i decided this, think safer , useful

  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 event "in-place" , inserts in 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 clock until next event time , event       ///is performed, if events list empty behavior undefined.       void next_event()       {          auto event = eventslist.top();          eventslist.pop();          currenttime = event.time();          event.perform();       }        ///calls next_event() while events list not empty.       void simulate()       { while (has_pending_events()) next_event();}         ///if t >= current_time(), performs of events time scheduled       ///before or @ moment t, , advances current time until t.        void simulate_until(const time_point& t)       {         if( t >= currenttime)         {           while(has_pending_events() , 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;    }; 

Comments

Popular posts from this blog

linux - xterm copying to CLIPBOARD using copy-selection causes automatic updating of CLIPBOARD upon mouse selection -

c++ - qgraphicsview horizontal scrolling always has a vertical delta -