Reformatted MTUtils with some refined directives.

Only whitespace changes in MTUtils.hpp !
This commit is contained in:
tamasmeszaros 2019-06-24 13:03:46 +02:00
parent 121b6c078b
commit 75ed542686
2 changed files with 128 additions and 80 deletions

View File

@ -18,7 +18,7 @@ AllowShortLoopsOnASingleLine: true
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: Yes
AlwaysBreakTemplateDeclarations: false
BinPackArguments: false
BinPackParameters: false
BraceWrapping:
@ -37,18 +37,18 @@ BraceWrapping:
SplitEmptyFunction: false
SplitEmptyRecord: false
SplitEmptyNamespace: false
BreakBeforeBinaryOperators: All
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Custom
BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeColon
BreakBeforeTernaryOperators: true
BreakBeforeTernaryOperators: false
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeComma
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 75
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
CompactNamespaces: true
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4

View File

@ -1,172 +1,218 @@
#ifndef MTUTILS_HPP
#define MTUTILS_HPP
#include <atomic> // for std::atomic_flag and memory orders
#include <mutex> // for std::lock_guard
#include <functional> // for std::function
#include <utility> // for std::forward
#include <atomic> // for std::atomic_flag and memory orders
#include <mutex> // for std::lock_guard
#include <functional> // for std::function
#include <utility> // for std::forward
#include <algorithm>
namespace Slic3r {
/// Handy little spin mutex for the cached meshes.
/// Implements the "Lockable" concept
class SpinMutex {
std::atomic_flag m_flg;
class SpinMutex
{
std::atomic_flag m_flg;
static const /*constexpr*/ auto MO_ACQ = std::memory_order_acquire;
static const /*constexpr*/ auto MO_REL = std::memory_order_release;
public:
inline SpinMutex() { m_flg.clear(MO_REL); }
inline void lock() { while(m_flg.test_and_set(MO_ACQ)); }
inline void lock() { while (m_flg.test_and_set(MO_ACQ)) ; }
inline bool try_lock() { return !m_flg.test_and_set(MO_ACQ); }
inline void unlock() { m_flg.clear(MO_REL); }
};
/// A wrapper class around arbitrary object that needs thread safe caching.
template<class T> class CachedObject {
template<class T> class CachedObject
{
public:
// Method type which refreshes the object when it has been invalidated
using Setter = std::function<void(T&)>;
using Setter = std::function<void(T &)>;
private:
T m_obj; // the object itself
bool m_valid; // invalidation flag
SpinMutex m_lck; // to make the caching thread safe
T m_obj; // the object itself
bool m_valid; // invalidation flag
SpinMutex m_lck; // to make the caching thread safe
// the setter will be called just before the object's const value is
// about to be retrieved.
std::function<void(T &)> m_setter;
// the setter will be called just before the object's const value is about
// to be retrieved.
std::function<void(T&)> m_setter;
public:
// Forwarded constructor
template<class...Args> inline CachedObject(Setter fn, Args&&...args):
m_obj(std::forward<Args>(args)...), m_valid(false), m_setter(fn) {}
template<class... Args>
inline CachedObject(Setter fn, Args &&... args)
: m_obj(std::forward<Args>(args)...), m_valid(false), m_setter(fn)
{}
// invalidate the value of the object. The object will be refreshed at the
// next retrieval (Setter will be called). The data that is used in
// the setter function should be guarded as well during modification so the
// modification has to take place in fn.
inline void invalidate(std::function<void()> fn) {
std::lock_guard<SpinMutex> lck(m_lck); fn(); m_valid = false;
// invalidate the value of the object. The object will be refreshed at
// the next retrieval (Setter will be called). The data that is used in
// the setter function should be guarded as well during modification so
// the modification has to take place in fn.
inline void invalidate(std::function<void()> fn)
{
std::lock_guard<SpinMutex> lck(m_lck);
fn();
m_valid = false;
}
// Get the const object properly updated.
inline const T& get() {
inline const T &get()
{
std::lock_guard<SpinMutex> lck(m_lck);
if(!m_valid) { m_setter(m_obj); m_valid = true; }
if (!m_valid) {
m_setter(m_obj);
m_valid = true;
}
return m_obj;
}
};
/// An std compatible random access iterator which uses indices to the source
/// vector thus resistant to invalidation caused by relocations. It also "knows"
/// its container. No comparison is neccesary to the container "end()" iterator.
/// The template can be instantiated with a different value type than that of
/// the container's but the types must be compatible. E.g. a base class of the
/// contained objects is compatible.
/// An std compatible random access iterator which uses indices to the
/// source vector thus resistant to invalidation caused by relocations. It
/// also "knows" its container. No comparison is neccesary to the container
/// "end()" iterator. The template can be instantiated with a different
/// value type than that of the container's but the types must be
/// compatible. E.g. a base class of the contained objects is compatible.
///
/// For a constant iterator, one can instantiate this template with a value
/// type preceded with 'const'.
template<class Vector, // The container type, must be random access...
template<class Vector, // The container type, must be random access...
class Value = typename Vector::value_type // The value type
>
class IndexBasedIterator {
class IndexBasedIterator
{
static const size_t NONE = size_t(-1);
std::reference_wrapper<Vector> m_index_ref;
size_t m_idx = NONE;
public:
size_t m_idx = NONE;
using value_type = Value;
using pointer = Value *;
using reference = Value &;
using difference_type = long;
public:
using value_type = Value;
using pointer = Value *;
using reference = Value &;
using difference_type = long;
using iterator_category = std::random_access_iterator_tag;
inline explicit
IndexBasedIterator(Vector& index, size_t idx):
m_index_ref(index), m_idx(idx) {}
inline explicit IndexBasedIterator(Vector &index, size_t idx)
: m_index_ref(index), m_idx(idx)
{}
// Post increment
inline IndexBasedIterator operator++(int) {
IndexBasedIterator cpy(*this); ++m_idx; return cpy;
inline IndexBasedIterator operator++(int)
{
IndexBasedIterator cpy(*this);
++m_idx;
return cpy;
}
inline IndexBasedIterator operator--(int) {
IndexBasedIterator cpy(*this); --m_idx; return cpy;
inline IndexBasedIterator operator--(int)
{
IndexBasedIterator cpy(*this);
--m_idx;
return cpy;
}
inline IndexBasedIterator& operator++() {
++m_idx; return *this;
inline IndexBasedIterator &operator++()
{
++m_idx;
return *this;
}
inline IndexBasedIterator& operator--() {
--m_idx; return *this;
inline IndexBasedIterator &operator--()
{
--m_idx;
return *this;
}
inline IndexBasedIterator& operator+=(difference_type l) {
m_idx += size_t(l); return *this;
inline IndexBasedIterator &operator+=(difference_type l)
{
m_idx += size_t(l);
return *this;
}
inline IndexBasedIterator operator+(difference_type l) {
auto cpy = *this; cpy += l; return cpy;
inline IndexBasedIterator operator+(difference_type l)
{
auto cpy = *this;
cpy += l;
return cpy;
}
inline IndexBasedIterator& operator-=(difference_type l) {
m_idx -= size_t(l); return *this;
inline IndexBasedIterator &operator-=(difference_type l)
{
m_idx -= size_t(l);
return *this;
}
inline IndexBasedIterator operator-(difference_type l) {
auto cpy = *this; cpy -= l; return cpy;
inline IndexBasedIterator operator-(difference_type l)
{
auto cpy = *this;
cpy -= l;
return cpy;
}
operator difference_type() { return difference_type(m_idx); }
/// Tesing the end of the container... this is not possible with std
/// iterators.
inline bool is_end() const { return m_idx >= m_index_ref.get().size();}
inline bool is_end() const
{
return m_idx >= m_index_ref.get().size();
}
inline Value & operator*() const {
inline Value &operator*() const
{
assert(m_idx < m_index_ref.get().size());
return m_index_ref.get().operator[](m_idx);
}
inline Value * operator->() const {
inline Value *operator->() const
{
assert(m_idx < m_index_ref.get().size());
return &m_index_ref.get().operator[](m_idx);
}
/// If both iterators point past the container, they are equal...
inline bool operator ==(const IndexBasedIterator& other) {
inline bool operator==(const IndexBasedIterator &other)
{
size_t e = m_index_ref.get().size();
return m_idx == other.m_idx || (m_idx >= e && other.m_idx >= e);
}
inline bool operator !=(const IndexBasedIterator& other) {
inline bool operator!=(const IndexBasedIterator &other)
{
return !(*this == other);
}
inline bool operator <=(const IndexBasedIterator& other) {
inline bool operator<=(const IndexBasedIterator &other)
{
return (m_idx < other.m_idx) || (*this == other);
}
inline bool operator <(const IndexBasedIterator& other) {
inline bool operator<(const IndexBasedIterator &other)
{
return m_idx < other.m_idx && (*this != other);
}
inline bool operator >=(const IndexBasedIterator& other) {
inline bool operator>=(const IndexBasedIterator &other)
{
return m_idx > other.m_idx || *this == other;
}
inline bool operator >(const IndexBasedIterator& other) {
inline bool operator>(const IndexBasedIterator &other)
{
return m_idx > other.m_idx && *this != other;
}
};
/// A very simple range concept implementation with iterator-like objects.
template<class It> class Range {
template<class It> class Range
{
It from, to;
public:
public:
// The class is ready for range based for loops.
It begin() const { return from; }
It end() const { return to; }
@ -175,15 +221,17 @@ public:
using Type = It;
Range() = default;
Range(It &&b, It &&e):
from(std::forward<It>(b)), to(std::forward<It>(e)) {}
Range(It &&b, It &&e)
: from(std::forward<It>(b)), to(std::forward<It>(e))
{}
// Some useful container-like methods...
inline size_t size() const { return end() - begin(); }
inline bool empty() const { return size() == 0; }
inline bool empty() const { return size() == 0; }
};
template<class C> bool all_of(const C &container) {
template<class C> bool all_of(const C &container)
{
return std::all_of(container.begin(),
container.end(),
[](const typename C::value_type &v) {
@ -200,6 +248,6 @@ template<class X, class Y> inline X ceil_i(X x, Y y)
return (x % y) ? x / y + 1 : x / y;
}
}
} // namespace Slic3r
#endif // MTUTILS_HPP