+// ****************************************************
+// Options predefined types and values
+
+namespace cds { namespace opt {
+
+ /// Predefined options value
+ namespace v {
+
+ /// Sequential non-atomic item counter
+ /**
+ This type of \p opt::item_counter option is not intended for concurrent containers
+ and may be used only if it is explicitly noted.
+ */
+ class sequential_item_counter
+ {
+ public:
+ typedef size_t counter_type ; ///< Counter type
+ protected:
+ counter_type m_nCounter ; ///< Counter
+
+ public:
+ sequential_item_counter()
+ : m_nCounter(0)
+ {}
+
+ /// Returns current value of the counter
+ counter_type value() const
+ {
+ return m_nCounter;
+ }
+
+ /// Same as \ref value() with relaxed memory ordering
+ operator counter_type() const
+ {
+ return value();
+ }
+
+ /// Increments the counter. Semantics: postincrement
+ counter_type inc()
+ {
+ return m_nCounter++;
+ }
+
+ /// Decrements the counter. Semantics: postdecrement
+ counter_type dec()
+ {
+ return m_nCounter--;
+ }
+
+ /// Preincrement
+ counter_type operator ++()
+ {
+ return inc() + 1;
+ }
+ /// Postincrement
+ counter_type operator ++(int)
+ {
+ return inc();
+ }
+
+ /// Predecrement
+ counter_type operator --()
+ {
+ return dec() - 1;
+ }
+ /// Postdecrement
+ counter_type operator --(int)
+ {
+ return dec();
+ }
+
+ /// Resets count to 0
+ void reset()
+ {
+ m_nCounter = 0;
+ }
+ };
+
+ /// Relaxed memory ordering \p opt::memory_model
+ /**
+ In this ordering the memory constraints are defined according to C++ Memory Model specification:
+ each constraint is mapped to \p std::memory_order constraints one-to-one
+ */
+ struct relaxed_ordering {
+ //@cond
+ static const atomics::memory_order memory_order_relaxed = atomics::memory_order_relaxed;
+ static const atomics::memory_order memory_order_consume = atomics::memory_order_consume;
+ static const atomics::memory_order memory_order_acquire = atomics::memory_order_acquire;
+ static const atomics::memory_order memory_order_release = atomics::memory_order_release;
+ static const atomics::memory_order memory_order_acq_rel = atomics::memory_order_acq_rel;
+ static const atomics::memory_order memory_order_seq_cst = atomics::memory_order_seq_cst;
+ //@endcond
+ };
+
+ /// Sequential consistent \p opt::memory_memory ordering
+ /**
+ In this memory model any memory constraint is equivalent to \p std::memory_order_seq_cst.
+ */
+ struct sequential_consistent {
+ //@cond
+ static const atomics::memory_order memory_order_relaxed = atomics::memory_order_seq_cst;
+ static const atomics::memory_order memory_order_consume = atomics::memory_order_seq_cst;
+ static const atomics::memory_order memory_order_acquire = atomics::memory_order_seq_cst;
+ static const atomics::memory_order memory_order_release = atomics::memory_order_seq_cst;
+ static const atomics::memory_order memory_order_acq_rel = atomics::memory_order_seq_cst;
+ static const atomics::memory_order memory_order_seq_cst = atomics::memory_order_seq_cst;
+ //@endcond
+ };
+
+ //@cond
+ /// Totally relaxed \p opt::memory_model ordering (do not use!)
+ /**
+ In this memory model any memory constraint is equivalent to \p std::memory_order_relaxed.
+ @warning Do not use this model! It intended for testing purposes only
+ to verify debugging instruments like Thread Sanitizer.
+ */
+ struct total_relaxed_ordering {
+ static const atomics::memory_order memory_order_relaxed = atomics::memory_order_relaxed;
+ static const atomics::memory_order memory_order_consume = atomics::memory_order_relaxed;
+ static const atomics::memory_order memory_order_acquire = atomics::memory_order_relaxed;
+ static const atomics::memory_order memory_order_release = atomics::memory_order_relaxed;
+ static const atomics::memory_order memory_order_acq_rel = atomics::memory_order_relaxed;
+ static const atomics::memory_order memory_order_seq_cst = atomics::memory_order_relaxed;
+ };
+ //@endcond
+
+
+ /// Default swap policy for \p opt::swap_policy option
+ /**
+ The default swap policy is wrappr around \p std::swap algorithm.
+ */
+ struct default_swap_policy {
+ /// Performs swapping of \p v1 and \p v2 using \p std::swap algo
+ template <typename T>
+ void operator()( T& v1, T& v2 ) const
+ {
+ std::swap( v1, v2 );
+ }
+ };
+
+ /// \p opt::move_policy based on move-assignment operator
+ struct assignment_move_policy
+ {
+ /// <tt> dest = std::move( src ) </tt>
+ template <typename T>
+ void operator()( T& dest, T&& src ) const
+ {
+ dest = std::move( src );
+ }
+ };
+
+ /// \p rand() -base random number generator for \p opt::random_engine
+ /**
+ This generator returns a pseudorandom integer in the range 0 to \p RAND_MAX (32767).
+ */
+ struct c_rand {
+ typedef unsigned int result_type; ///< Result type
+
+ /// Constructor initializes object calling \p std::srand()
+ c_rand()
+ {
+ std::srand(1);
+ }
+
+ /// Returns next random number calling \p std::rand()
+ result_type operator()()
+ {
+ return (result_type) std::rand();
+ }
+ };
+ } // namespace v
+
+}} // namespace cds::opt
+