Skip to content

Instantly share code, notes, and snippets.

@Chippiewill
Created June 19, 2017 22:06
Show Gist options
  • Save Chippiewill/2f19ac1d1096ca2b9e9e916ff40cc30a to your computer and use it in GitHub Desktop.
Save Chippiewill/2f19ac1d1096ca2b9e9e916ff40cc30a to your computer and use it in GitHub Desktop.
template <class Clock, class Duration = typename Clock::duration>
class atomic_time_point {
public:
using clock = Clock;
using base_time_point = typename std::chrono::time_point<Clock, Duration>;
using duration = Duration;
using rep = typename duration::rep;
constexpr atomic_time_point() {}
constexpr explicit atomic_time_point(const duration& d)
: timeSinceEpoch(d.count()) {
}
template<class Duration2>
constexpr atomic_time_point(const std::chrono::time_point<Clock,Duration2>& t)
: timeSinceEpoch(duration(t.time_since_epoch()).count()) {
}
template<class Duration2>
atomic_time_point& operator=(const std::chrono::time_point<Clock,Duration2>& t){
timeSinceEpoch = duration(t.time_since_epoch()).count();
return *this;
}
constexpr duration time_since_epoch(std::memory_order order = std::memory_order_seq_cst) const {
return duration(timeSinceEpoch.load(order));
}
atomic_time_point& operator+=(const duration& d) {
timeSinceEpoch += d.count();
return *this;
}
atomic_time_point& operator-=(const duration& d) {
timeSinceEpoch -= d.count();
return *this;
}
static constexpr base_time_point min() {
return Clock::time_point::min();
}
static constexpr base_time_point max() {
return Clock::time_point::max();
}
base_time_point load(std::memory_order order = std::memory_order_seq_cst) const {
return base_time_point(time_since_epoch(order));
}
operator base_time_point() const {
return load();
}
template<class Duration2>
int compare(const std::chrono::time_point<Clock,Duration2>& t, std::memory_order order = std::memory_order_seq_cst) const {
auto ours = time_since_epoch(order);
auto theirs = t.time_since_epoch();
if (ours > theirs) {
return 1;
} else if (theirs > ours) {
return - 1;
}
return 0;
}
template<class Duration2>
int compare(const atomic_time_point<Clock, Duration2>& t, std::memory_order order = std::memory_order_seq_cst) const {
return compare(t.load(order), order);
}
template<class Duration2>
void setIfGreater(const std::chrono::time_point<Clock,Duration2>& t) {
rep newValue = duration(t.time_since_epoch()).count();
rep oldValue = timeSinceEpoch.load();
while (newValue > oldValue) {
if (timeSinceEpoch.compare_exchange_strong(oldValue, newValue)) {
break;
}
oldValue = timeSinceEpoch.load();
}
}
private:
std::atomic<rep> timeSinceEpoch{0};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment