fixed adding file problem
[c11concurrency-benchmarks.git] / gdax-orderbook-hpp / demo / dependencies / libcds-2.3.2 / cds / opt / permutation.h
diff --git a/gdax-orderbook-hpp/demo/dependencies/libcds-2.3.2/cds/opt/permutation.h b/gdax-orderbook-hpp/demo/dependencies/libcds-2.3.2/cds/opt/permutation.h
new file mode 100644 (file)
index 0000000..a69b57f
--- /dev/null
@@ -0,0 +1,329 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef CDSLIB_OPT_PERMUTATION_H
+#define CDSLIB_OPT_PERMUTATION_H
+
+#include <cstdlib> // rand, srand
+#include <random>
+#include <algorithm> // std::shuffle
+#include <numeric>   // std::iota
+
+#include <cds/opt/options.h>
+
+namespace cds { namespace opt {
+
+    /// [type-option] Random permutation generator option setter
+    /**
+        The class represents permutation generator of unique integers from <tt> [0, nLength) </tt>
+        (\p nLenght is not included) in random order.
+
+        The generator interface is:
+        \code
+        class generator {
+            // Initializes the generator of length nLength
+            generator( size_t nLength );
+
+            // Returns current value
+            operator int();
+
+            // Goes to next value. Returns false if the permutation is exchausted
+            bool next();
+
+            // Resets the generator to produce the new sequence
+            void reset();
+        };
+        \endcode
+
+        <b>Usage example</b>
+
+        The permutation generator is intended for <tt>do {} while</tt> loop:
+        \code
+        permutation_generator gen( 16 );
+        int i = gen.begin();
+        do {
+            int i = gen;
+            //...
+        } while ( gen.next());
+
+        // Get other permutation
+        gen.reset();
+        do {
+            int i = gen;
+            //...
+        } while ( gen.next());
+        \endcode
+
+        The following \p Generator defined:
+        - \p opt::v::random_permutation
+        - \p opt::v::random2_permutation
+        - \p opt::v::random_shuffle_permutation
+        - \p opt::v::skew_permutation
+    */
+    template <typename Generator>
+    struct permutation_generator {
+        //@cond
+        template <typename Base> struct pack: public Base
+        {
+            typedef Generator permutation_generator;
+        };
+        //@endcond
+    };
+
+    namespace v {
+
+        /// Permutation generator of arbitrary length based on \p rand()
+        /**
+            The class is suitable for \p opt::permutation_generator option.
+
+            The generator calculates <tt>n = rand()</tt> and produces the sequence
+            <tt>[n % nLen, (n + 1) % nLen, ..., (n + nLen - 1) % nLen]</tt>.
+            The generator does not allocate any memory.
+
+            \p Int template argument specifies the type of generated value, it should be any integer.
+        */
+        template <typename Int=int>
+        class random_permutation
+        {
+        public:
+            typedef Int     integer_type;   ///< Type of generated value
+        protected:
+            //@cond
+            integer_type        m_nCur;
+            integer_type        m_nStart;
+            integer_type const  m_nMod;
+            //@endcond
+
+        public:
+            /// Initializes the generator of arbitrary length \p nLength
+            random_permutation( size_t nLength )
+                : m_nCur(0)
+                , m_nStart(0)
+                , m_nMod( integer_type(nLength))
+            {
+                reset();
+            }
+
+            /// Returns the curent value
+            operator integer_type() const
+            {
+                return m_nCur % m_nMod;
+            }
+
+            /// Goes to next value. Returns \p false if the sequence is exhausted
+            bool next()
+            {
+                return (++m_nCur % m_nMod) != m_nStart;
+            }
+
+            /// Resets the generator to produce new sequence
+            void reset()
+            {
+                m_nCur = m_nStart = integer_type( std::rand()) % m_nMod;
+            }
+        };
+
+        /// Permutation generator of power-of-2 length based on \p rand()
+        /**
+            The class is suitable for \p opt::permutation_generator option.
+
+            The generator calculates <tt>n = rand()</tt> and produces the sequence
+            <tt>[n % nLen, (n + 1) % nLen, ..., (n + nLen - 1) % nLen]</tt>.
+            The generator does not allocate any memory.
+            \p nLen must be power of two.
+
+            \p Int template argument specifies the type of generated value, it should be any integer.
+        */
+        template <typename Int=int>
+        class random2_permutation
+        {
+        public:
+            typedef Int     integer_type;   ///< Type of generated value
+
+        protected:
+            //@cond
+            integer_type        m_nCur;
+            integer_type        m_nStart;
+            integer_type const  m_nMask;
+            //@endcond
+
+        public:
+            /// Initializes the generator of length \p nLength
+            /**
+                An assertion is raised if \p nLength is not a power of two.
+            */
+            random2_permutation( size_t nLength )
+                : m_nCur(0)
+                , m_nStart(0)
+                , m_nMask( integer_type(nLength) - 1 )
+            {
+                // nLength must be power of two
+                assert( (nLength & (nLength - 1)) == 0 );
+                reset();
+            }
+
+            /// Returns the current value
+            operator integer_type() const
+            {
+                return m_nCur & m_nMask;
+            }
+
+            /// Goes to next value. Returns \p false if the sequence is exhausted
+            bool next()
+            {
+                return (++m_nCur & m_nMask) != m_nStart;
+            }
+
+            /// Resets the generator to produce new sequence
+            void reset()
+            {
+                m_nCur = m_nStart = integer_type( std::rand()) & m_nMask;
+            }
+        };
+
+        /// Permutation generator based on \p std::shuffle
+        /**
+            The class is suitable for \p opt::permutation_generator option.
+
+            The generator produces a permutation of <tt>[0, nLen)</tt> sequence.
+            The generator instance allocates a memory block.
+
+            Template parameters:
+            - \p Int - specifies the type of generated value, it should be any integer.
+            - \p RandomGenerator - random generator, default is \p std::mt19937
+            - \p RandomDevice - random device, default is \p std::random_device
+        */
+        template <typename Int=int, class RandomGenerator = std::mt19937, class RandomDevice = std::random_device >
+        class random_shuffle_permutation
+        {
+        public:
+            typedef Int     integer_type;             ///< Type of generated value
+            typedef RandomGenerator random_generator; ///< random generator
+            typedef RandomDevice random_device;       ///< random device
+
+        protected:
+            //@cond
+            integer_type *      m_pCur;
+            integer_type *      m_pFirst;
+            integer_type *      m_pLast;
+            //@endcond
+
+        public:
+            /// Initializes the generator of arbitrary length \p nLength
+            random_shuffle_permutation( size_t nLength )
+                : m_pCur( nullptr )
+            {
+                m_pFirst = new integer_type[nLength];
+                m_pLast = m_pFirst + nLength;
+                std::iota(m_pFirst, m_pLast, integer_type{0} );
+                reset();
+            }
+
+            ~random_shuffle_permutation()
+            {
+                delete [] m_pFirst;
+            }
+
+            /// Returns the current value
+            operator integer_type() const
+            {
+                return *m_pCur;
+            }
+
+            /// Goes to next value. Returns \p false if the sequence is exhausted
+            bool next()
+            {
+                return ++m_pCur < m_pLast;
+            }
+
+            /// Resets the generator to produce new sequence
+            void reset()
+            {
+                std::shuffle( m_pFirst, m_pLast, random_generator{ random_device{}() });
+                m_pCur = m_pFirst;
+            }
+        };
+
+        /// Skew permutation generator
+        /**
+            This generator produces offset permutation based on \p Generator:
+                <tt>int(Generator) + nOffset</tt>
+            where \p Generator - a permutation generator.
+
+            The class is suitable for \p opt::permutation_generator option
+            if the goal sequence should be a permutation of <tt>[nOffset, nOffset + nLength)</tt>
+        */
+        template <typename Generator>
+        class skew_permutation
+        {
+        public:
+            typedef Generator base_generator;   ///< Original permutation generator
+            typedef typename base_generator::integer_type   integer_type; ///< Type of generated value
+
+        protected:
+            //@cond
+            base_generator      m_Gen;
+            integer_type const  m_nOffset;
+            //@endcond
+
+        public:
+            /// Initializes the generator
+            skew_permutation(
+                integer_type nOffset,   ///< The offset, i.e. first value of generated sequence
+                size_t nLength          ///< The length of sequence
+                )
+                : m_Gen( nLength )
+                , m_nOffset( nOffset )
+            {}
+
+            /// Returns the current value
+            operator integer_type() const
+            {
+                return integer_type(m_Gen) + m_nOffset;
+            }
+
+            /// Goes to next value. Returns \p false if the sequence is exhausted
+            bool next()
+            {
+                return m_Gen.next();
+            }
+
+            /// Resets the generator to produce new sequence
+            void reset()
+            {
+                m_Gen.reset();
+            }
+        };
+
+    } // namespace v
+
+}} // namespace cds::opt
+
+#endif // #ifndef CDSLIB_OPT_PERMUTATION_H