void lock() { while (1) { while (m_lock == to_underlying(lock_state::LOCKED)); long old = to_underlying(lock_state::UNLOCKED); if (m_lock.compare_exchange_weak(old, to_underlying(lock_state::LOCKED), std::memory_order_release, std::memory_order_relaxed)) return; } }
int try_lock() { if (value()) return -1; long old = to_underlying(lock_state::UNLOCKED); if (m_lock.compare_exchange_weak(old, to_underlying(lock_state::LOCKED), std::memory_order_release, std::memory_order_relaxed)) return 0; else return -1; }
inline bool operator==(Property const& lft, Property const& rgt) { // note: not checking table_column // ordered roughly by the cost of the check return to_underlying(lft.type) == to_underlying(rgt.type) && lft.is_primary == rgt.is_primary && lft.requires_index() == rgt.requires_index() && lft.name == rgt.name && lft.object_type == rgt.object_type && lft.link_origin_property_name == rgt.link_origin_property_name; }
void read_lock() { long oldval, newval; while (1) { // lower bit is 1 when there's a write lock while ((oldval = value()) == to_underlying(lock_state::LOCKED)); newval = oldval + 2; if (m_lock.compare_exchange_weak(oldval, newval, std::memory_order_release, std::memory_order_relaxed)) break; } }
void buildPathFromBFS(uvec2 start, TDPath& path, const CellMap& graph) { uvec2 current = start; Assert((graph[start].bfs & to_underlying(NodeInfo::Visited)) > 0, "goal unreachable from this start"); Assert(path.empty()); while (!(graph[current].bfs & to_underlying(NodeInfo::IsGoal))) { path.push_back(current); if (graph[current].bfs & to_underlying(NodeInfo::PlusX)) ++current.x; else if (graph[current].bfs & to_underlying(NodeInfo::MinusX)) --current.x; else if (graph[current].bfs & to_underlying(NodeInfo::PlusY)) ++current.y; else if (graph[current].bfs & to_underlying(NodeInfo::MinusY)) --current.y; Assert(current < graph.size); } path.push_back(current); }
bool is_numeric() const { return to_underlying(_type_id) <= to_underlying(FieldTypeId::INT64); }
inline constexpr PropertyType operator&(PropertyType a, PropertyType b) { return static_cast<PropertyType>(to_underlying(a) & to_underlying(b)); }
inline constexpr bool is_nullable(PropertyType a) { return to_underlying(a & PropertyType::Nullable) == to_underlying(PropertyType::Nullable); }
inline constexpr bool is_array(PropertyType a) { return to_underlying(a & PropertyType::Array) == to_underlying(PropertyType::Array); }
inline constexpr bool operator==(PropertyType a, PropertyType b) { return to_underlying(a & ~PropertyType::Flags) == to_underlying(b & ~PropertyType::Flags); }
void unlock() { m_lock.store(to_underlying(lock_state::UNLOCKED), std::memory_order_relaxed); }
spin_lock() : m_lock(to_underlying(lock_state::UNLOCKED)) {}
constexpr E operator|(E l, E r) { return static_cast<E>(to_underlying(l) | to_underlying(r)); }
void computeBreadthFirstSearch(uvec2 goal, CellMap& graph) { std::queue<uvec2> frontier; uvec2 current; uvec2 next; Assert(goal < graph.size, "goal is out of bounds"); Assert((graph[goal].bfs & to_underlying(NodeInfo::Pathable)) != 0, "goal is not pathable"); graph[goal].bfs |= to_underlying(NodeInfo::IsGoal); frontier.push(goal); while (!frontier.empty()) { current = frontier.front(); frontier.pop(); // Visiting neighbors // x - 1 if (current.x > 0) { next = uvec2(current.x - 1, current.y); if (graph[next].bfs & to_underlying(NodeInfo::Pathable) && !(graph[next].bfs & to_underlying(NodeInfo::Visited))) { frontier.push(next); graph[next].bfs |= to_underlying(NodeInfo::Visited) | to_underlying(NodeInfo::PlusX); } } // x + 1 if (current.x + 1 < graph.size.x) { next = uvec2(current.x + 1, current.y); if (graph[next].bfs & to_underlying(NodeInfo::Pathable) && !(graph[next].bfs & to_underlying(NodeInfo::Visited))) { frontier.push(next); graph[next].bfs |= to_underlying(NodeInfo::Visited) | to_underlying(NodeInfo::MinusX); } } // y - 1 if (current.y > 0) { next = uvec2(current.x, current.y - 1); if (graph[next].bfs & to_underlying(NodeInfo::Pathable) && !(graph[next].bfs & to_underlying(NodeInfo::Visited))) { frontier.push(next); graph[next].bfs |= to_underlying(NodeInfo::Visited) | to_underlying(NodeInfo::PlusY); } } // y + 1 if (current.y + 1 < graph.size.y) { next = uvec2(current.x, current.y + 1); if (graph[next].bfs & to_underlying(NodeInfo::Pathable) && !(graph[next].bfs & to_underlying(NodeInfo::Visited))) { frontier.push(next); graph[next].bfs |= to_underlying(NodeInfo::Visited) | to_underlying(NodeInfo::MinusY); } } } // Remove any direction we set graph[goal].bfs &= ~ (to_underlying(NodeInfo::PlusX) | to_underlying(NodeInfo::MinusX) | to_underlying(NodeInfo::PlusY) | to_underlying(NodeInfo::MinusY)); }
constexpr bool enum_sanity_check (T last, T count) { return ((to_underlying(count) - to_underlying(last)) == 1); }