code:
//
//  Copyright (c) 2000-2002
//  Joerg Walter, Mathias Koch
//
//  Distributed under the Boost Software License, Version 1.0. (See
//  accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//
//  The authors gratefully acknowledge the support of
//  GeNeSys mbH & Co. KG in producing this work.
//

#ifndef BOOST_UBLAS_STORAGE_H
#define BOOST_UBLAS_STORAGE_H

#include <algorithm>
#ifdef BOOST_UBLAS_SHALLOW_ARRAY_ADAPTOR
#include <boost/shared_array.hpp>
#endif

#include <boost/serialization/array.hpp>
#include <boost/serialization/collection_size_type.hpp>
#include <boost/serialization/nvp.hpp>

#include <boost/numeric/ublas/exception.hpp>
#include <boost/numeric/ublas/traits.hpp>
#include <boost/numeric/ublas/detail/iterator.hpp>

namespace boost { namespace numeric { namespace ublas {

    // Base class for Storage Arrays - see the Barton Nackman trick
    template<class E>
    class storage_array:
        private nonassignable {
    };

    // Unbounded array - with allocator
    template<class T, class ALLOC>
    class unbounded_array:
        public storage_array<unbounded_array<T, ALLOC> > {

        typedef unbounded_array<T, ALLOC> self_type;
    public:
        typedef ALLOC allocator_type;
        typedef typename ALLOC::size_type size_type;
        typedef typename ALLOC::difference_type difference_type;
        typedef T value_type;
        typedef const T &const_reference;
        typedef T &reference;
        typedef const T *const_pointer;
        typedef T *pointer;
        typedef const_pointer const_iterator;
        typedef pointer iterator;

        // Construction and destruction
        explicit BOOST_UBLAS_INLINE
        unbounded_array (const ALLOC &a = ALLOC()):
            alloc_ (a), size_ (0) {
            data_ = 0;
        }
        explicit BOOST_UBLAS_INLINE
        unbounded_array (size_type size, const ALLOC &a = ALLOC()):
            alloc_(a), size_ (size) {
          if (size_) {
              data_ = alloc_.allocate (size_);
              if (! detail::has_trivial_constructor<T>::value) {
                  for (pointer d = data_; d != data_ + size_; ++d)
                      alloc_.construct(d, value_type());
              }
          }
          else
              data_ = 0;
        }
        // No value initialised, but still be default constructed
        BOOST_UBLAS_INLINE
        unbounded_array (size_type size, const value_type &init, const ALLOC &a = ALLOC()):
            alloc_ (a), size_ (size) {
            if (size_) {
                data_ = alloc_.allocate (size_);
                std::uninitialized_fill (begin(), end(), init);
            }
            else
                data_ = 0;
        }
        BOOST_UBLAS_INLINE
        unbounded_array (const unbounded_array &c):
            storage_array<unbounded_array<T, ALLOC> >(),
            alloc_ (c.alloc_), size_ (c.size_) {
            if (size_) {
                data_ = alloc_.allocate (size_);
                std::uninitialized_copy (c.begin(), c.end(), begin());
            }
            else
                data_ = 0;
        }
        BOOST_UBLAS_INLINE
        ~unbounded_array () {
            if (size_) {
                if (! detail::has_trivial_destructor<T>::value) {
                    // std::_Destroy (begin(), end(), alloc_);
                    const iterator i_end = end();
                    for (iterator i = begin (); i != i_end; ++i) {
                        iterator_destroy (i);
                    }
                }
                alloc_.deallocate (data_, size_);
            }
        }

        // Resizing
    private:
        BOOST_UBLAS_INLINE
        void resize_internal (const size_type size, const value_type init, const bool preserve) {
            if (size != size_) {
                pointer p_data = data_;
                if (size) {
                    data_ = alloc_.allocate (size);
                    if (preserve) {
                        pointer si = p_data;
                        pointer di = data_;
                        if (size < size_) {
                            for (; di != data_ + size; ++di) {
                                alloc_.construct (di, *si);
                                ++si;
                            }
                        }
                        else {
                            for (; si != p_data + size_; ++si) {
                                alloc_.construct (di, *si);
                                ++di;
                            }
                            for (; di != data_ + size; ++di) {
                                alloc_.construct (di, init);
                            }
                        }
                    }
                    else {
                        if (! detail::has_trivial_constructor<T>::value) {
                            for (pointer di = data_; di != data_ + size; ++di)
                                alloc_.construct (di, value_type());
                        }
                    }
                }

                if (size_) {
                    if (! detail::has_trivial_destructor<T>::value) {
                        for (pointer si = p_data; si != p_data + size_; ++si)
                            alloc_.destroy (si);
                    }
                    alloc_.deallocate (p_data, size_);
                }

                if (!size)
                    data_ = 0;
                size_ = size;
            }
        }
    public:
        BOOST_UBLAS_INLINE
        void resize (size_type size) {
            resize_internal (size, value_type (), false);
        }
        BOOST_UBLAS_INLINE
        void resize (size_type size, value_type init) {
            resize_internal (size, init, true);
        }

        // Random Access Container
        BOOST_UBLAS_INLINE
        size_type max_size () const {
            return ALLOC ().max_size();
        }

        BOOST_UBLAS_INLINE
        bool empty () const {
            return size_ == 0;
        }

        BOOST_UBLAS_INLINE
        size_type size () const {
            return size_;
        }

        // Element access
        BOOST_UBLAS_INLINE
        const_reference operator [] (size_type i) const {
            BOOST_UBLAS_CHECK (i < size_, bad_index ());
            return data_ [i];
        }
        BOOST_UBLAS_INLINE
        reference operator [] (size_type i) {
            BOOST_UBLAS_CHECK (i < size_, bad_index ());
            return data_ [i];
        }

        // Assignment
        BOOST_UBLAS_INLINE
        unbounded_array &operator = (const unbounded_array &a) {
            if (this != &a) {
                resize (a.size_);
                std::copy (a.data_, a.data_ + a.size_, data_);
            }
            return *this;
        }
        BOOST_UBLAS_INLINE
        unbounded_array &assign_temporary (unbounded_array &a) {
            swap (a);
            return *this;
        }

        // Swapping
        BOOST_UBLAS_INLINE
        void swap (unbounded_array &a) {
            if (this != &a) {
                std::swap (size_, a.size_);
                std::swap (data_, a.data_);
            }
        }
        BOOST_UBLAS_INLINE
        friend void swap (unbounded_array &a1, unbounded_array &a2) {
            a1.swap (a2);
        }

        BOOST_UBLAS_INLINE
        const_iterator begin () const {
            return data_;
        }
        BOOST_UBLAS_INLINE
        const_iterator cbegin () const {
            return begin ();
        }
        BOOST_UBLAS_INLINE
        const_iterator end () const {
            return data_ + size_;
        }
        BOOST_UBLAS_INLINE
        const_iterator cend () const {
            return end ();
        }

        BOOST_UBLAS_INLINE
        iterator begin () {
            return data_;
        }
        BOOST_UBLAS_INLINE
        iterator end () {
            return data_ + size_;
        }

        // Reverse iterators
        typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
        typedef std::reverse_iterator<iterator> reverse_iterator;

        BOOST_UBLAS_INLINE
        const_reverse_iterator rbegin () const {
            return const_reverse_iterator (end ());
        }
        BOOST_UBLAS_INLINE
        const_reverse_iterator crbegin () const {
            return rbegin ();
        }
        BOOST_UBLAS_INLINE
        const_reverse_iterator rend () const {
            return const_reverse_iterator (begin ());
        }
        BOOST_UBLAS_INLINE
        const_reverse_iterator crend () const {
            return rend ();
        }
        BOOST_UBLAS_INLINE
        reverse_iterator rbegin () {
            return reverse_iterator (end ());
        }
        BOOST_UBLAS_INLINE
        reverse_iterator rend () {
            return reverse_iterator (begin ());
        }

        // Allocator
        allocator_type get_allocator () {
            return alloc_;
        }

    private:
        friend class boost::serialization::access;

        // Serialization
        template<class Archive>
        void serialize(Archive & ar, const unsigned int /*version*/)
        {
            serialization::collection_size_type s(size_);
            ar & serialization::make_nvp("size",s);
            if ( Archive::is_loading::value ) {
                resize(s);
            }
            ar & serialization::make_array(data_, s);
        }

    private:
        // Handle explict destroy on a (possibly indexed) iterator
        BOOST_UBLAS_INLINE
        static void iterator_destroy (iterator &i) {
            (&(*i)) -> ~value_type ();
        }
        ALLOC alloc_;
        size_type size_;
        pointer data_;
    };

    // Bounded array - with allocator for size_type and difference_type
    template<class T, std::size_t N, class ALLOC>
    class bounded_array:
        public storage_array<bounded_array<T, N, ALLOC> > {

        typedef bounded_array<T, N, ALLOC> self_type;
    public:
        // No allocator_type as ALLOC is not used for allocation
        typedef typename ALLOC::size_type size_type;
        typedef typename ALLOC::difference_type difference_type;
        typedef T value_type;
        typedef const T &const_reference;
        typedef T &reference;
        typedef const T *const_pointer;
        typedef T *pointer;
        typedef const_pointer const_iterator;
        typedef pointer iterator;

        // Construction and destruction
        BOOST_UBLAS_INLINE
        bounded_array ():
            size_ (0) /*, data_ ()*/ {   // size 0 - use bounded_vector to default construct with size N
        }
        explicit BOOST_UBLAS_INLINE
        bounded_array (size_type size):
            size_ (size) /*, data_ ()*/ {
            BOOST_UBLAS_CHECK (size_ <= N, bad_size ());
            // data_ (an array) elements are already default constructed
        }
        BOOST_UBLAS_INLINE
        bounded_array (size_type size, const value_type &init):
            size_ (size) /*, data_ ()*/ {
            BOOST_UBLAS_CHECK (size_ <= N, bad_size ());
            // ISSUE elements should be value constructed here, but we must fill instead as already default constructed
            std::fill (begin(), end(), init) ;
        }
        BOOST_UBLAS_INLINE
        bounded_array (const bounded_array &c):
            size_ (c.size_)  {
            // ISSUE elements should be copy constructed here, but we must copy instead as already default constructed
            std::copy (c.begin(), c.end(), begin());
        }

        // Resizing
        BOOST_UBLAS_INLINE
        void resize (size_type size) {
            BOOST_UBLAS_CHECK (size <= N, bad_size ());
            size_ = size;
        }
        BOOST_UBLAS_INLINE
        void resize (size_type size, value_type init) {
            BOOST_UBLAS_CHECK (size <= N, bad_size ());
            if (size > size_)
                std::fill (data_ + size_, data_ + size, init);
            size_ = size;
        }

        // Random Access Container
        BOOST_UBLAS_INLINE
        size_type max_size () const {
            return N;
        }

        BOOST_UBLAS_INLINE
        bool empty () const {
            return size_ == 0;
        }

        BOOST_UBLAS_INLINE
        size_type size () const {
            return size_;
        }

        // Element access
        BOOST_UBLAS_INLINE
        const_reference operator [] (size_type i) const {
            BOOST_UBLAS_CHECK (i < size_, bad_index ());
            return data_ [i];
        }
        BOOST_UBLAS_INLINE
        reference operator [] (size_type i) {
            BOOST_UBLAS_CHECK (i < size_, bad_index ());
            return data_ [i];
        }

        // Assignment
        BOOST_UBLAS_INLINE
        bounded_array &operator = (const bounded_array &a) {
            if (this != &a) {
                resize (a.size_);
                std::copy (a.data_, a.data_ + a.size_, data_);
            }
            return *this;
        }
        BOOST_UBLAS_INLINE
        bounded_array &assign_temporary (bounded_array &a) {
            *this = a;
            return *this;
        }

        // Swapping
        BOOST_UBLAS_INLINE
        void swap (bounded_array &a) {
            if (this != &a) {
                std::swap (size_, a.size_);
                std::swap_ranges (data_, data_ + (std::max) (size_, a.size_), a.data_);
            }
        }
        BOOST_UBLAS_INLINE
        friend void swap (bounded_array &a1, bounded_array &a2) {
            a1.swap (a2);
        }

        BOOST_UBLAS_INLINE
        const_iterator begin () const {
            return data_;
        }
        BOOST_UBLAS_INLINE
        const_iterator cbegin () const {
            return begin ();
        }
        BOOST_UBLAS_INLINE
        const_iterator end () const {
            return data_ + size_;
        }
        BOOST_UBLAS_INLINE
        const_iterator cend () const {
            return end ();
        }

        BOOST_UBLAS_INLINE
        iterator begin () {
            return data_;
        }
        BOOST_UBLAS_INLINE
        iterator end () {
            return data_ + size_;
        }

        // Reverse iterators
        typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
        typedef std::reverse_iterator<iterator> reverse_iterator;

        BOOST_UBLAS_INLINE
        const_reverse_iterator rbegin () const {
            return const_reverse_iterator (end ());
        }
        BOOST_UBLAS_INLINE
        const_reverse_iterator crbegin () const {
            return rbegin ();
        }
        BOOST_UBLAS_INLINE
        const_reverse_iterator rend () const {
            return const_reverse_iterator (begin ());
        }
        BOOST_UBLAS_INLINE
        const_reverse_iterator crend () const {
            return rend ();
        }
        BOOST_UBLAS_INLINE
        reverse_iterator rbegin () {
            return reverse_iterator (end ());
        }
        BOOST_UBLAS_INLINE
        reverse_iterator rend () {
            return reverse_iterator (begin ());
        }

    private:
        // Serialization
        friend class boost::serialization::access;

        template<class Archive>
        void serialize(Archive & ar, const unsigned int /*version*/)
        {
            serialization::collection_size_type s(size_);
            ar & serialization::make_nvp("size", s);
            if ( Archive::is_loading::value ) {
                if (s > N) bad_size("too large size in bounded_array::load()\n").raise();
                resize(s);
            }
            ar & serialization::make_array(data_, s);
        }

    private:
        size_type size_;
// MSVC does not like arrays of size 0 in base classes.  Hence, this conditionally changes the size to 1
#ifdef _MSC_VER
        BOOST_UBLAS_BOUNDED_ARRAY_ALIGN value_type data_ [(N>0)?N:1];
#else
        BOOST_UBLAS_BOUNDED_ARRAY_ALIGN value_type data_ [N];
#endif
    };

    // Array adaptor with normal deep copy semantics of elements
    template<class T>
    class array_adaptor:
        public storage_array<array_adaptor<T> > {

        typedef array_adaptor<T> self_type;
    public:
        typedef std::size_t size_type;
        typedef std::ptrdiff_t difference_type;
        typedef T value_type;
        typedef const T &const_reference;
        typedef T &reference;
        typedef const T *const_pointer;
        typedef T *pointer;

        // Construction and destruction
        BOOST_UBLAS_INLINE
        array_adaptor ():
            size_ (0), own_ (true), data_ (new value_type [0]) {
        }
        explicit BOOST_UBLAS_INLINE
        array_adaptor (size_type size):
            size_ (size), own_ (true), data_ (new value_type [size]) {
        }
        BOOST_UBLAS_INLINE
        array_adaptor (size_type size, const value_type &init):
            size_ (size), own_ (true), data_ (new value_type [size]) {
            std::fill (data_, data_ + size_, init);
        }
        BOOST_UBLAS_INLINE
        array_adaptor (size_type size, pointer data):
            size_ (size), own_ (false), data_ (data) {}

        template <size_t N>
        BOOST_UBLAS_INLINE array_adaptor (T (&data)[N]):
            size_ (N), own_ (false), data_ (data) {}
        BOOST_UBLAS_INLINE
        array_adaptor (const array_adaptor &a):
            storage_array<self_type> (),
            size_ (a.size_), own_ (true), data_ (new value_type [a.size_]) {
            *this = a;
        }
        BOOST_UBLAS_INLINE
        ~array_adaptor () {
            if (own_) {
                delete [] data_;
            }
        }

        // Resizing
    private:
        BOOST_UBLAS_INLINE
        void resize_internal (size_type size, value_type init, bool preserve = true) {
           if (size != size_) {
                pointer data = new value_type [size];
                if (preserve) {
                    std::copy (data_, data_ + (std::min) (size, size_), data);
                    std::fill (data + (std::min) (size, size_), data + size, init);
                }
                if (own_)
                    delete [] data_;
                size_ = size;
                own_ = true;
                data_ = data;
            }
        }
        BOOST_UBLAS_INLINE
        void resize_internal (size_type size, pointer data, value_type init, bool preserve = true) {
            if (data != data_) {
                if (preserve) {
                    std::copy (data_, data_ + (std::min) (size, size_), data);
                    std::fill (data + (std::min) (size, size_), data + size, init);
                }
                if (own_)
                    delete [] data_;
                own_ = false;
                data_ = data;
            }
            else {
                std::fill (data + (std::min) (size, size_), data + size, init);
            }
            size_ = size;
        }
    public:
        BOOST_UBLAS_INLINE
        void resize (size_type size) {
            resize_internal (size, value_type (), false);
        }
        BOOST_UBLAS_INLINE
        void resize (size_type size, value_type init) {
            resize_internal (size, init, true);
        }
        BOOST_UBLAS_INLINE
        void resize (size_type size, pointer data) {
            resize_internal (size, data, value_type (), false);
        }
        BOOST_UBLAS_INLINE
        void resize (size_type size, pointer data, value_type init) {
            resize_internal (size, data, init, true);
        }

        template <size_t N>
        BOOST_UBLAS_INLINE void resize (T (&data)[N]) {
            resize_internal (N, data, value_type (), false);
        }

        template <size_t N>
        BOOST_UBLAS_INLINE void resize (T (&data)[N], value_type init) {
            resize_internal (N, data, init, true);
        }

        BOOST_UBLAS_INLINE
        size_type size () const {
            return size_;
        }

        // Element access
        BOOST_UBLAS_INLINE
        const_reference operator [] (size_type i) const {
            BOOST_UBLAS_CHECK (i < size_, bad_index ());
            return data_ [i];
        }
        BOOST_UBLAS_INLINE
        reference operator [] (size_type i) {
            BOOST_UBLAS_CHECK (i < size_, bad_index ());
            return data_ [i];
        }

        // Assignment
        BOOST_UBLAS_INLINE
        array_adaptor &operator = (const array_adaptor &a) {
            if (this != &a) {
                resize (a.size_);
                std::copy (a.data_, a.data_ + a.size_, data_);
            }
            return *this;
        }
        BOOST_UBLAS_INLINE
        array_adaptor &assign_temporary (array_adaptor &a) {
            if (own_ && a.own_)
                swap (a);
            else
                *this = a;
            return *this;
        }

        // Swapping
        BOOST_UBLAS_INLINE
        void swap (array_adaptor &a) {
            if (this != &a) {
                std::swap (size_, a.size_);
                std::swap (own_, a.own_);
                std::swap (data_, a.data_);
            }
        }
        BOOST_UBLAS_INLINE
        friend void swap (array_adaptor &a1, array_adaptor &a2) {
            a1.swap (a2);
        }

        // Iterators simply are pointers.

        typedef const_pointer const_iterator;

        BOOST_UBLAS_INLINE
        const_iterator begin () const {
            return data_;
        }
        BOOST_UBLAS_INLINE
        const_iterator cbegin () const {
            return begin ();
        }
        BOOST_UBLAS_INLINE
        const_iterator end () const {
            return data_ + size_;
        }
        BOOST_UBLAS_INLINE
        const_iterator cend () const {
            return end ();
        }

        typedef pointer iterator;

        BOOST_UBLAS_INLINE
        iterator begin () {
            return data_;
        }
        BOOST_UBLAS_INLINE
        iterator end () {
            return data_ + size_;
        }

        // Reverse iterators
        typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
        typedef std::reverse_iterator<iterator> reverse_iterator;

        BOOST_UBLAS_INLINE
        const_reverse_iterator rbegin () const {
            return const_reverse_iterator (end ());
        }
        BOOST_UBLAS_INLINE
        const_reverse_iterator crbegin () const {
            return rbegin ();
        }
        BOOST_UBLAS_INLINE
        const_reverse_iterator rend () const {
            return const_reverse_iterator (begin ());
        }
        BOOST_UBLAS_INLINE
        const_reverse_iterator crend () const {
            return rend ();
        }
        BOOST_UBLAS_INLINE
        reverse_iterator rbegin () {
            return reverse_iterator (end ());
        }
        BOOST_UBLAS_INLINE
        reverse_iterator rend () {
            return reverse_iterator (begin ());
        }

    private:
        size_type size_;
        bool own_;
        pointer data_;
    };

#ifdef BOOST_UBLAS_SHALLOW_ARRAY_ADAPTOR
    // Array adaptor with shallow (reference) copy semantics of elements.
    // shared_array is used to maintain reference counts.
    // This class breaks the normal copy semantics for a storage container and is very dangerous!
    template<class T>
    class shallow_array_adaptor:
        public storage_array<shallow_array_adaptor<T> > {

        typedef shallow_array_adaptor<T> self_type;

        template<class TT>
        struct leaker {
            typedef void result_type;
            typedef TT *argument_type;

            BOOST_UBLAS_INLINE
            result_type operator () (argument_type /* x */) {}
        };

    public:
        typedef std::size_t size_type;
        typedef std::ptrdiff_t difference_type;
        typedef T value_type;
        typedef const T &const_reference;
        typedef T &reference;
        typedef const T *const_pointer;
        typedef T *pointer;

        // Construction and destruction
        BOOST_UBLAS_INLINE
        shallow_array_adaptor ():
            size_ (0), own_ (true), data_ (new value_type [0]) {
        }
        explicit BOOST_UBLAS_INLINE
        shallow_array_adaptor (size_type size):
            size_ (size), own_ (true), data_ (new value_type [size]) {
        }
        BOOST_UBLAS_INLINE
        shallow_array_adaptor (size_type size, const value_type &init):
            size_ (size), own_ (true), data_ (new value_type [size]) {
            std::fill (data_.get (), data_.get () + size_, init);
        }
        BOOST_UBLAS_INLINE
        shallow_array_adaptor (size_type size, pointer data):
            size_ (size), own_ (false), data_ (data, leaker<value_type> ()) {}
        template <size_t N>
        BOOST_UBLAS_INLINE
        shallow_array_adaptor (T (&data)[N]):
            size_ (N), own_ (false), data_ (data, leaker<value_type> ()) {}

        BOOST_UBLAS_INLINE
        shallow_array_adaptor (const shallow_array_adaptor &a):
            storage_array<self_type> (),
            size_ (a.size_), own_ (a.own_), data_ (a.data_) {}

        BOOST_UBLAS_INLINE
        ~shallow_array_adaptor () {
        }

        // Resizing
    private:
        BOOST_UBLAS_INLINE
        void resize_internal (size_type size, value_type init, bool preserve = true) {
            if (size != size_) {
                shared_array<value_type> data (new value_type [size]);
                if (preserve) {
                    std::copy (data_.get (), data_.get () + (std::min) (size, size_), data.get ());
                    std::fill (data.get () + (std::min) (size, size_), data.get () + size, init);
                }
                size_ = size;
                own_ = true;
                data_ = data;
            }
        }
        BOOST_UBLAS_INLINE
        void resize_internal (size_type size, pointer data, value_type init, bool preserve = true) {
            if (preserve) {
                std::copy (data_.get (), data_.get () + (std::min) (size, size_), data);
                std::fill (data + (std::min) (size, size_), data + size, init);
            }
            size_ = size;
            own_ = false;
            data_.reset(data, leaker<value_type> ());
        }
    public:
        BOOST_UBLAS_INLINE
        void resize (size_type size) {
            resize_internal (size, value_type (), false);
        }
        BOOST_UBLAS_INLINE
        void resize (size_type size, value_type init) {
            resize_internal (size, init, true);
        }
        BOOST_UBLAS_INLINE
        void resize (size_type size, pointer data) {
            resize_internal (size, data, value_type (), false);
        }
        BOOST_UBLAS_INLINE
        void resize (size_type size, pointer data, value_type init) {
            resize_internal (size, data, init, true);
        }
        template <size_t N>
        BOOST_UBLAS_INLINE
        void resize (T (&data)[N]) {
            resize_internal (N, data, value_type (), false);
        }
        template <size_t N>
        BOOST_UBLAS_INLINE
        void resize (T (&data)[N], value_type init) {
            resize_internal (N, data, init, true);
        }

        BOOST_UBLAS_INLINE
        size_type size () const {
            return size_;
        }

        // Element access
        BOOST_UBLAS_INLINE
        const_reference operator [] (size_type i) const {
            BOOST_UBLAS_CHECK (i < size_, bad_index ());
            return data_ [i];
        }
        BOOST_UBLAS_INLINE
        reference operator [] (size_type i) {
            BOOST_UBLAS_CHECK (i < size_, bad_index ());
            return data_ [i];
        }

        // Assignment
        BOOST_UBLAS_INLINE
        shallow_array_adaptor &operator = (const shallow_array_adaptor &a) {
            if (this != &a) {
                resize (a.size_);
                std::copy (a.data_.get (), a.data_.get () + a.size_, data_.get ());
            }
            return *this;
        }
        BOOST_UBLAS_INLINE
        shallow_array_adaptor &assign_temporary (shallow_array_adaptor &a) {
            if (own_ && a.own_)
                swap (a);
            else
                *this = a;
            return *this;
        }

        // Swapping
        BOOST_UBLAS_INLINE
        void swap (shallow_array_adaptor &a) {
            if (this != &a) {
                std::swap (size_, a.size_);
                std::swap (own_, a.own_);
                std::swap (data_, a.data_);
            }
        }
        BOOST_UBLAS_INLINE
        friend void swap (shallow_array_adaptor &a1, shallow_array_adaptor &a2) {
            a1.swap (a2);
        }

        // Iterators simply are pointers.

        typedef const_pointer const_iterator;

        BOOST_UBLAS_INLINE
        const_iterator begin () const {
            return data_.get ();
        }
        BOOST_UBLAS_INLINE
        const_iterator cbegin () const {
            return begin ();
        }
        BOOST_UBLAS_INLINE
        const_iterator end () const {
            return data_.get () + size_;
        }
        BOOST_UBLAS_INLINE
        const_iterator cend () const {
            return end ();
        }

        typedef pointer iterator;

        BOOST_UBLAS_INLINE
        iterator begin () {
            return data_.get ();
        }
        BOOST_UBLAS_INLINE
        iterator end () {
            return data_.get () + size_;
        }

        // Reverse iterators
        typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
        typedef std::reverse_iterator<iterator> reverse_iterator;

        BOOST_UBLAS_INLINE
        const_reverse_iterator rbegin () const {
            return const_reverse_iterator (end ());
        }
        BOOST_UBLAS_INLINE
        const_reverse_iterator crbegin () const {
            return rbegin ();
        }
        BOOST_UBLAS_INLINE
        const_reverse_iterator rend () const {
            return const_reverse_iterator (begin ());
        }
        BOOST_UBLAS_INLINE
        const_reverse_iterator crend () const {
            return rend ();
        }
        BOOST_UBLAS_INLINE
        reverse_iterator rbegin () {
            return reverse_iterator (end ());
        }
        BOOST_UBLAS_INLINE
        reverse_iterator rend () {
            return reverse_iterator (begin ());
        }

    private:
        size_type size_;
        bool own_;
        shared_array<value_type> data_;
    };

#endif

    // Range class
    template <class Z, class D>
    class basic_range {
        typedef basic_range<Z, D> self_type;
    public:
        typedef Z size_type;
        typedef D difference_type;
        typedef size_type value_type;
        typedef value_type const_reference;
        typedef const_reference reference;
        typedef const value_type *const_pointer;
        typedef value_type *pointer;

        // Construction and destruction
        BOOST_UBLAS_INLINE
        basic_range ():
            start_ (0), size_ (0) {}
        BOOST_UBLAS_INLINE
        basic_range (size_type start, size_type stop):
            start_ (start), size_ (stop - start) {
            BOOST_UBLAS_CHECK (start_ <= stop, bad_index ());
        }

        BOOST_UBLAS_INLINE
        size_type start () const {
            return start_;
        }
        BOOST_UBLAS_INLINE
        size_type size () const {
            return size_;
        }

        // Random Access Container
        BOOST_UBLAS_INLINE
        size_type max_size () const {
            return size_;
        }

        BOOST_UBLAS_INLINE
        bool empty () const {
            return size_ == 0;
        }

        // Element access
        BOOST_UBLAS_INLINE
        const_reference operator () (size_type i) const {
            BOOST_UBLAS_CHECK (i < size_, bad_index ());
            return start_ + i;
        }

        // Composition
        BOOST_UBLAS_INLINE
        basic_range compose (const basic_range &r) const {
            return basic_range (start_ + r.start_, start_ + r.start_ + r.size_);
        }

        // Comparison
        BOOST_UBLAS_INLINE
        bool operator == (const basic_range &r) const {
            return start_ == r.start_ && size_ == r.size_;
        }
        BOOST_UBLAS_INLINE
        bool operator != (const basic_range &r) const {
            return ! (*this == r);
        }

        // Iterator types
    private:
        // Use and index
        typedef size_type const_subiterator_type;

    public:
#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
        typedef indexed_const_iterator<self_type, std::random_access_iterator_tag> const_iterator;
#else
        class const_iterator:
            public container_const_reference<basic_range>,
            public random_access_iterator_base<std::random_access_iterator_tag,
                                               const_iterator, value_type> {
        public:
            typedef typename basic_range::value_type value_type;
            typedef typename basic_range::difference_type difference_type;
            typedef typename basic_range::const_reference reference;
            typedef typename basic_range::const_pointer pointer;

            // Construction and destruction
            BOOST_UBLAS_INLINE
            const_iterator ():
                container_const_reference<basic_range> (), it_ () {}
            BOOST_UBLAS_INLINE
            const_iterator (const basic_range &r, const const_subiterator_type &it):
                container_const_reference<basic_range> (r), it_ (it) {}

            // Arithmetic
            BOOST_UBLAS_INLINE
            const_iterator &operator ++ () {
                ++ it_;
                return *this;
            }
            BOOST_UBLAS_INLINE
            const_iterator &operator -- () {
                BOOST_UBLAS_CHECK (it_ > 0, bad_index ());
                -- it_;
                return *this;
            }
            BOOST_UBLAS_INLINE
            const_iterator &operator += (difference_type n) {
                BOOST_UBLAS_CHECK (n >= 0 || it_ >= size_type(-n), bad_index ());
                it_ += n;
                return *this;
            }
            BOOST_UBLAS_INLINE
            const_iterator &operator -= (difference_type n) {
                BOOST_UBLAS_CHECK (n <= 0 || it_ >= size_type(n), bad_index ());
                it_ -= n;
                return *this;
            }
            BOOST_UBLAS_INLINE
            difference_type operator - (const const_iterator &it) const {
                return it_ - it.it_;
            }

            // Dereference
            BOOST_UBLAS_INLINE
            const_reference operator * () const {
                BOOST_UBLAS_CHECK ((*this) ().start () <= it_, bad_index ());
                BOOST_UBLAS_CHECK (it_ < (*this) ().start () + (*this) ().size (), bad_index ());
                return it_;
            }

            BOOST_UBLAS_INLINE
            const_reference operator [] (difference_type n) const {
                return *(*this + n);
            }

            // Index
            BOOST_UBLAS_INLINE
            size_type index () const {
                BOOST_UBLAS_CHECK ((*this) ().start () <= it_, bad_index ());
                BOOST_UBLAS_CHECK (it_ < (*this) ().start () + (*this) ().size (), bad_index ());
                return it_ - (*this) ().start ();
            }

            // Assignment
            BOOST_UBLAS_INLINE
            const_iterator &operator = (const const_iterator &it) {
                // Comeau recommends...
                this->assign (&it ());
                it_ = it.it_;
                return *this;
            }

            // Comparison
            BOOST_UBLAS_INLINE
            bool operator == (const const_iterator &it) const {
                BOOST_UBLAS_CHECK ((*this) () == it (), external_logic ());
                return it_ == it.it_;
            }
            BOOST_UBLAS_INLINE
            bool operator < (const const_iterator &it) const {
                BOOST_UBLAS_CHECK ((*this) () == it (), external_logic ());
                return it_ < it.it_;
            }

        private:
            const_subiterator_type it_;
        };
#endif

        BOOST_UBLAS_INLINE
        const_iterator begin () const {
            return const_iterator (*this, start_);
        }
        BOOST_UBLAS_INLINE
        const_iterator cbegin () const {
            return begin ();
        }
        BOOST_UBLAS_INLINE
        const_iterator end () const {
            return const_iterator (*this, start_ + size_);
        }
        BOOST_UBLAS_INLINE
        const_iterator cend () const {
            return end ();
        }

        // Reverse iterator
        typedef std::reverse_iterator<const_iterator> const_reverse_iterator;

        BOOST_UBLAS_INLINE
        const_reverse_iterator rbegin () const {
            return const_reverse_iterator (end ());
        }
        BOOST_UBLAS_INLINE
        const_reverse_iterator crbegin () const {
            return rbegin ();
        }
        BOOST_UBLAS_INLINE
        const_reverse_iterator rend () const {
            return const_reverse_iterator (begin ());
        }
        BOOST_UBLAS_INLINE
        const_reverse_iterator crend () const {
            return rend ();
        }

        BOOST_UBLAS_INLINE
        basic_range preprocess (size_type size) const {
            if (this != &all_)
                return *this;
            return basic_range (0, size);
        }
        static
        BOOST_UBLAS_INLINE
        const basic_range &all () {
            return all_;
        }

    private:
        size_type start_;
        size_type size_;
        static const basic_range all_;
    };

    template <class Z, class D>
    const basic_range<Z,D> basic_range<Z,D>::all_  (0, size_type (-1));

    // Slice class
    template <class Z, class D>
    class basic_slice {
        typedef basic_slice<Z, D> self_type;
    public:
        typedef Z size_type;
        typedef D difference_type;
        typedef size_type value_type;
        typedef value_type const_reference;
        typedef const_reference reference;
        typedef const value_type *const_pointer;
        typedef value_type *pointer;

        // Construction and destruction
        BOOST_UBLAS_INLINE
        basic_slice ():
            start_ (0), stride_ (0), size_ (0) {}
        BOOST_UBLAS_INLINE
        basic_slice (size_type start, difference_type stride, size_type size):
            start_ (start), stride_ (stride), size_ (size) {}

        BOOST_UBLAS_INLINE
        size_type start () const {
            return start_;
        }
        BOOST_UBLAS_INLINE
        difference_type stride () const {
            return stride_;
        }
        BOOST_UBLAS_INLINE
        size_type size () const {
            return size_;
        }

        // Random Access Container
        BOOST_UBLAS_INLINE
        size_type max_size () const {
            return size_;
        }

        BOOST_UBLAS_INLINE
        bool empty () const {
            return size_ == 0;
        }

        // Element access
        BOOST_UBLAS_INLINE
        const_reference operator () (size_type i) const {
            BOOST_UBLAS_CHECK (i < size_, bad_index ());
            BOOST_UBLAS_CHECK (stride_ >= 0 || start_ >= i * -stride_, bad_index ());
            return start_ + i * stride_;
        }

        // Composition
        BOOST_UBLAS_INLINE
        basic_slice compose (const basic_range<size_type, difference_type> &r) const {
            BOOST_UBLAS_CHECK (stride_ >=0 || start_ >= -stride_ * r.start(), bad_index ());
            return basic_slice (start_ + stride_ * r.start (), stride_, r.size ());
        }
        BOOST_UBLAS_INLINE
        basic_slice compose (const basic_slice &s) const {
            BOOST_UBLAS_CHECK (stride_ >=0 || start_ >= -stride_ * s.start_, bad_index ());
            return basic_slice (start_ + stride_ * s.start_, stride_ * s.stride_, s.size_);
        }

        // Comparison
        BOOST_UBLAS_INLINE
        bool operator == (const basic_slice &s) const {
            return start_ == s.start_ && stride_ == s.stride_ && size_ == s.size_;
        }
        BOOST_UBLAS_INLINE
        bool operator != (const basic_slice &s) const {
            return ! (*this == s);
        }

        // Iterator types
    private:
        // Use and index
        typedef size_type const_subiterator_type;

    public:
#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
        typedef indexed_const_iterator<self_type, std::random_access_iterator_tag> const_iterator;
#else
        class const_iterator:
            public container_const_reference<basic_slice>,
            public random_access_iterator_base<std::random_access_iterator_tag,
                                               const_iterator, value_type> {
        public:
            typedef typename basic_slice::value_type value_type;
            typedef typename basic_slice::difference_type difference_type;
            typedef typename basic_slice::const_reference reference;
            typedef typename basic_slice::const_pointer pointer;

            // Construction and destruction
            BOOST_UBLAS_INLINE
            const_iterator ():
                container_const_reference<basic_slice> (), it_ () {}
            BOOST_UBLAS_INLINE
            const_iterator (const basic_slice &s, const const_subiterator_type &it):
                container_const_reference<basic_slice> (s), it_ (it) {}

            // Arithmetic
            BOOST_UBLAS_INLINE
            const_iterator &operator ++ () {
                ++it_;
                return *this;
            }
            BOOST_UBLAS_INLINE
            const_iterator &operator -- () {
                BOOST_UBLAS_CHECK (it_ > 0, bad_index ());
                --it_;
                return *this;
            }
            BOOST_UBLAS_INLINE
            const_iterator &operator += (difference_type n) {
                BOOST_UBLAS_CHECK (n >= 0 || it_ >= size_type(-n), bad_index ());
                it_ += n;
                return *this;
            }
            BOOST_UBLAS_INLINE
            const_iterator &operator -= (difference_type n) {
                BOOST_UBLAS_CHECK (n <= 0 || it_ >= size_type(n), bad_index ());
                it_ -= n;
                return *this;
            }
            BOOST_UBLAS_INLINE
            difference_type operator - (const const_iterator &it) const {
                return it_ - it.it_;
            }

            // Dereference
            BOOST_UBLAS_INLINE
            const_reference operator * () const {
                BOOST_UBLAS_CHECK (it_ < (*this) ().size (), bad_index ());
                return (*this) ().start () + it_* (*this) ().stride ();
            }

            BOOST_UBLAS_INLINE
            const_reference operator [] (difference_type n) const {
                return *(*this + n);
            }

            // Index
            BOOST_UBLAS_INLINE
            size_type index () const {
                BOOST_UBLAS_CHECK (it_ < (*this) ().size (), bad_index ());
                return it_;
            }

            // Assignment
            BOOST_UBLAS_INLINE
            const_iterator &operator = (const const_iterator &it) {
                // Comeau recommends...
                this->assign (&it ());
                it_ = it.it_;
                return *this;
            }

            // Comparison
            BOOST_UBLAS_INLINE
            bool operator == (const const_iterator &it) const {
                BOOST_UBLAS_CHECK ((*this) () == it (), external_logic ());
                return it_ == it.it_;
            }
            BOOST_UBLAS_INLINE
            bool operator < (const const_iterator &it) const {
                BOOST_UBLAS_CHECK ((*this) () == it (), external_logic ());
                return it_ < it.it_;
            }

        private:
            const_subiterator_type it_;
        };
#endif

        BOOST_UBLAS_INLINE
        const_iterator begin () const {
            return const_iterator (*this, 0);
        }
        BOOST_UBLAS_INLINE
        const_iterator cbegin () const {
            return begin ();
        }
        BOOST_UBLAS_INLINE
        const_iterator end () const {
            return const_iterator (*this, size_);
        }
        BOOST_UBLAS_INLINE
        const_iterator cend () const {
            return end ();
        }

        // Reverse iterator
        typedef std::reverse_iterator<const_iterator> const_reverse_iterator;

        BOOST_UBLAS_INLINE
        const_reverse_iterator rbegin () const {
            return const_reverse_iterator (end ());
        }
        BOOST_UBLAS_INLINE
        const_reverse_iterator crbegin () const {
            return rbegin ();
        }
        BOOST_UBLAS_INLINE
        const_reverse_iterator rend () const {
            return const_reverse_iterator (begin ());
        }
        BOOST_UBLAS_INLINE
        const_reverse_iterator crend () const {
            return rend ();
        }

        BOOST_UBLAS_INLINE
        basic_slice preprocess (size_type size) const {
            if (this != &all_)
                return *this;
            return basic_slice (0, 1, size);
        }
        static
        BOOST_UBLAS_INLINE
        const basic_slice &all () {
            return all_;
        }

    private:
        size_type start_;
        difference_type stride_;
        size_type size_;
        static const basic_slice all_;
    };

    template <class Z, class D>
    const basic_slice<Z,D> basic_slice<Z,D>::all_  (0, 1, size_type (-1));

    // Indirect array class
    template<class A>
    class indirect_array {
        typedef indirect_array<A> self_type;
    public:
        typedef A array_type;
        typedef const A const_array_type;
        typedef typename A::size_type size_type;
        typedef typename A::difference_type difference_type;
        typedef typename A::value_type value_type;
        typedef typename A::const_reference const_reference;
        typedef typename A::reference reference;
        typedef typename A::const_pointer const_pointer;
        typedef typename A::pointer pointer;

        // Construction and destruction
        BOOST_UBLAS_INLINE
        indirect_array ():
            size_ (), data_ () {}
        explicit BOOST_UBLAS_INLINE
        indirect_array (size_type size):
            size_ (size), data_ (size) {}
        BOOST_UBLAS_INLINE
        indirect_array (size_type size, const array_type &data):
            size_ (size), data_ (data) {}
        BOOST_UBLAS_INLINE
        indirect_array (pointer start, pointer stop):
            size_ (stop - start), data_ (stop - start) {
            std::copy (start, stop, data_.begin ());
        }

        BOOST_UBLAS_INLINE
        size_type size () const {
            return size_;
        }
        BOOST_UBLAS_INLINE
        const_array_type data () const {
            return data_;
        }
        BOOST_UBLAS_INLINE
        array_type data () {
            return data_;
        }

        // Random Access Container
        BOOST_UBLAS_INLINE
        size_type max_size () const {
            return size_;
        }

        BOOST_UBLAS_INLINE
        bool empty () const {
            return data_.size () == 0;
        }

        // Element access
        BOOST_UBLAS_INLINE
        const_reference operator () (size_type i) const {
            BOOST_UBLAS_CHECK (i < size_, bad_index ());
            return data_ [i];
        }
        BOOST_UBLAS_INLINE
        reference operator () (size_type i) {
            BOOST_UBLAS_CHECK (i < size_, bad_index ());
            return data_ [i];
        }

        BOOST_UBLAS_INLINE
        const_reference operator [] (size_type i) const {
            return (*this) (i);
        }
        BOOST_UBLAS_INLINE
        reference operator [] (size_type i) {
            return (*this) (i);
        }

        // Composition
        BOOST_UBLAS_INLINE
        indirect_array compose (const basic_range<size_type, difference_type> &r) const {
            BOOST_UBLAS_CHECK (r.start () + r.size () <= size_, bad_size ());
            array_type data (r.size ());
            for (size_type i = 0; i < r.size (); ++ i)
                data [i] = data_ [r.start () + i];
            return indirect_array (r.size (), data);
        }
        BOOST_UBLAS_INLINE
        indirect_array compose (const basic_slice<size_type, difference_type> &s) const {
            BOOST_UBLAS_CHECK (s.start () + s.stride () * (s.size () - (s.size () > 0)) <= size (), bad_size ());
            array_type data (s.size ());
            for (size_type i = 0; i < s.size (); ++ i)
                data [i] = data_ [s.start () + s.stride () * i];
            return indirect_array (s.size (), data);
        }
        BOOST_UBLAS_INLINE
        indirect_array compose (const indirect_array &ia) const {
            array_type data (ia.size_);
            for (size_type i = 0; i < ia.size_; ++ i) {
                BOOST_UBLAS_CHECK (ia.data_ [i] <= size_, bad_size ());
                data [i] = data_ [ia.data_ [i]];
            }
            return indirect_array (ia.size_, data);
        }

        // Comparison
        template<class OA>
        BOOST_UBLAS_INLINE
        bool operator == (const indirect_array<OA> &ia) const {
            if (size_ != ia.size_)
                return false;
            for (size_type i = 0; i < BOOST_UBLAS_SAME (size_, ia.size_); ++ i)
                if (data_ [i] != ia.data_ [i])
                    return false;
            return true;
        }
        template<class OA>
        BOOST_UBLAS_INLINE
        bool operator != (const indirect_array<OA> &ia) const {
            return ! (*this == ia);
        }

        // Iterator types
    private:
        // Use a index difference
        typedef difference_type const_subiterator_type;

    public:
#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
        typedef indexed_const_iterator<indirect_array, std::random_access_iterator_tag> const_iterator;
#else
        class const_iterator:
            public container_const_reference<indirect_array>,
            public random_access_iterator_base<std::random_access_iterator_tag,
                                               const_iterator, value_type> {
        public:
            typedef typename indirect_array::value_type value_type;
            typedef typename indirect_array::difference_type difference_type;
            typedef typename indirect_array::const_reference reference;
            typedef typename indirect_array::const_pointer pointer;

            // Construction and destruction
            BOOST_UBLAS_INLINE
            const_iterator ():
                container_const_reference<indirect_array> (), it_ () {}
            BOOST_UBLAS_INLINE
            const_iterator (const indirect_array &ia, const const_subiterator_type &it):
                container_const_reference<indirect_array> (ia), it_ (it) {}

            // Arithmetic
            BOOST_UBLAS_INLINE
            const_iterator &operator ++ () {
                ++ it_;
                return *this;
            }
            BOOST_UBLAS_INLINE
            const_iterator &operator -- () {
                -- it_;
                return *this;
            }
            BOOST_UBLAS_INLINE
            const_iterator &operator += (difference_type n) {
                it_ += n;
                return *this;
            }
            BOOST_UBLAS_INLINE
            const_iterator &operator -= (difference_type n) {
                it_ -= n;
                return *this;
            }
            BOOST_UBLAS_INLINE
            difference_type operator - (const const_iterator &it) const {
                return it_ - it.it_;
            }

            // Dereference
            BOOST_UBLAS_INLINE
            const_reference operator * () const {
                return (*this) () (it_);
            }

            BOOST_UBLAS_INLINE
            const_reference operator [] (difference_type n) const {
                return *(*this + n);
            }

            // Index
            BOOST_UBLAS_INLINE
            size_type index () const {
                return it_;
            }

            // Assignment
            BOOST_UBLAS_INLINE
            const_iterator &operator = (const const_iterator &it) {
                // Comeau recommends...
                this->assign (&it ());
                it_ = it.it_;
                return *this;
            }

            // Comparison
            BOOST_UBLAS_INLINE
            bool operator == (const const_iterator &it) const {
                BOOST_UBLAS_CHECK ((*this) () == it (), external_logic ());
                return it_ == it.it_;
            }
            BOOST_UBLAS_INLINE
            bool operator < (const const_iterator &it) const {
                BOOST_UBLAS_CHECK ((*this) () == it (), external_logic ());
                return it_ < it.it_;
            }

        private:
            const_subiterator_type it_;
        };
#endif

        BOOST_UBLAS_INLINE
        const_iterator begin () const {
            return const_iterator (*this, 0);
        }
        BOOST_UBLAS_INLINE
        const_iterator cbegin () const {
            return begin ();
        }
        BOOST_UBLAS_INLINE
        const_iterator end () const {
            return const_iterator (*this, size_);
        }
        BOOST_UBLAS_INLINE
        const_iterator cend () const {
            return end ();
        }

        // Reverse iterator
        typedef std::reverse_iterator<const_iterator> const_reverse_iterator;

        BOOST_UBLAS_INLINE
        const_reverse_iterator rbegin () const {
            return const_reverse_iterator (end ());
        }
        BOOST_UBLAS_INLINE
        const_reverse_iterator crbegin () const {
            return rbegin ();
        }
        BOOST_UBLAS_INLINE
        const_reverse_iterator rend () const {
            return const_reverse_iterator (begin ());
        }
        BOOST_UBLAS_INLINE
        const_reverse_iterator crend () const {
            return rend ();
        }

        BOOST_UBLAS_INLINE
        indirect_array preprocess (size_type size) const {
            if (this != &all_)
                return *this;
            indirect_array ia (size);
            for (size_type i = 0; i < size; ++ i)
               ia (i) = i;
            return ia;
        }
        static
        BOOST_UBLAS_INLINE
        const indirect_array &all () {
            return all_;
        }

    private:
        size_type size_;
        array_type data_;
        static const indirect_array all_;
    };

    template<class A>
    const indirect_array<A> indirect_array<A>::all_;

    // Gunter Winkler contributed the classes index_pair, index_pair_array,
    // index_triple and index_triple_array to enable inplace sort of parallel arrays.

    template <class V>
    class index_pair :
        public container_reference<V> {

        typedef index_pair<V> self_type;
    public:
        typedef typename V::size_type size_type;

        BOOST_UBLAS_INLINE
        index_pair(V& v, size_type i) :
            container_reference<V>(v), i_(i),
            v1_(v.data1_[i]), v2_(v.data2_[i]),
            dirty_(false), is_copy_(false) {}
         BOOST_UBLAS_INLINE
        index_pair(const self_type& rhs) :
            container_reference<V>(rhs()), i_(0),
            v1_(rhs.v1_), v2_(rhs.v2_),
            dirty_(false), is_copy_(true) {}
         BOOST_UBLAS_INLINE
        ~index_pair() {
            if (dirty_ && (!is_copy_) ) {
                (*this)().data1_[i_] = v1_;
                (*this)().data2_[i_] = v2_;
            }
        }

        BOOST_UBLAS_INLINE
        self_type& operator=(const self_type& rhs) {
            v1_ = rhs.v1_;
            v2_ = rhs.v2_;
            dirty_ = true;
            return *this;
        }

        BOOST_UBLAS_INLINE
        void swap(self_type& rhs) {
            self_type tmp(rhs);
            rhs = *this;
            *this = tmp;
        }

        BOOST_UBLAS_INLINE
        friend void swap(self_type& lhs, self_type& rhs) {
            lhs.swap(rhs);
        }

        friend void swap(self_type lhs, self_type rhs) { // For gcc 4.8 and c++11
            lhs.swap(rhs);
        }

        BOOST_UBLAS_INLINE
        bool equal(const self_type& rhs) const {
            return (v1_ == rhs.v1_);
        }
        BOOST_UBLAS_INLINE
        bool less(const self_type& rhs) const {
            return (v1_ < rhs.v1_);
        }
        BOOST_UBLAS_INLINE
        friend bool operator == (const self_type& lhs, const self_type& rhs) {
            return lhs.equal(rhs);
        }
        BOOST_UBLAS_INLINE
        friend bool operator != (const self_type& lhs, const self_type& rhs) {
            return !lhs.equal(rhs);
        }
        BOOST_UBLAS_INLINE
        friend bool operator < (const self_type& lhs, const self_type& rhs) {
            return lhs.less(rhs);
        }
        BOOST_UBLAS_INLINE
        friend bool operator >= (const self_type& lhs, const self_type& rhs) {
            return !lhs.less(rhs);
        }
        BOOST_UBLAS_INLINE
        friend bool operator > (const self_type& lhs, const self_type& rhs) {
            return rhs.less(lhs);
        }
        BOOST_UBLAS_INLINE
        friend bool operator <= (const self_type& lhs, const self_type& rhs) {
            return !rhs.less(lhs);
        }

    private:
        size_type i_;
        typename V::value1_type v1_;
        typename V::value2_type v2_;
        bool dirty_;
        bool is_copy_;
     };

    template <class V1, class V2>
    class index_pair_array:
        private boost::noncopyable {

        typedef index_pair_array<V1, V2> self_type;
    public:
        typedef typename V1::value_type value1_type;
        typedef typename V2::value_type value2_type;

        typedef typename V1::size_type size_type;
        typedef typename V1::difference_type difference_type;
        typedef index_pair<self_type> value_type;
        // There is nothing that can be referenced directly. Always return a copy of the index_pair
        typedef value_type reference;
        typedef const value_type const_reference;

        BOOST_UBLAS_INLINE
        index_pair_array(size_type size, V1& data1, V2& data2) :
              size_(size),data1_(data1),data2_(data2) {}

        BOOST_UBLAS_INLINE
        size_type size() const {
            return size_;
        }

        BOOST_UBLAS_INLINE
        const_reference operator () (size_type i) const {
            return value_type((*this), i);
        }
        BOOST_UBLAS_INLINE
        reference operator () (size_type i) {
            return value_type((*this), i);
        }

        typedef indexed_iterator<self_type, std::random_access_iterator_tag> iterator;
        typedef indexed_const_iterator<self_type, std::random_access_iterator_tag> const_iterator;

        BOOST_UBLAS_INLINE
        iterator begin() {
            return iterator( (*this), 0);
        }
        BOOST_UBLAS_INLINE
        iterator end() {
            return iterator( (*this), size());
        }

        BOOST_UBLAS_INLINE
        const_iterator begin() const {
            return const_iterator( (*this), 0);
        }
        BOOST_UBLAS_INLINE
        const_iterator cbegin () const {
            return begin ();
        }
        BOOST_UBLAS_INLINE
        const_iterator end() const {
            return const_iterator( (*this), size());
        }
        BOOST_UBLAS_INLINE
        const_iterator cend () const {
            return end ();
        }

        // unnecessary function:
        BOOST_UBLAS_INLINE
        bool equal(size_type i1, size_type i2) const {
            return data1_[i1] == data1_[i2];
        }
        BOOST_UBLAS_INLINE
        bool less(size_type i1, size_type i2) const {
            return data1_[i1] < data1_[i2];
        }

        // gives a large speedup
        BOOST_UBLAS_INLINE
        friend void iter_swap(const iterator& lhs, const iterator& rhs) {
            const size_type i1 = lhs.index();
            const size_type i2 = rhs.index();
            std::swap(lhs().data1_[i1], rhs().data1_[i2]);
            std::swap(lhs().data2_[i1], rhs().data2_[i2]);
        }

    private:
        size_type size_;
        V1& data1_;
        V2& data2_;

        // friend class value_type;
        friend class index_pair<self_type>;
    };

    template <class M>
    class index_triple :
        public container_reference<M> {

        typedef index_triple<M> self_type;
    public:
        typedef typename M::size_type size_type;

        BOOST_UBLAS_INLINE
        index_triple(M& m, size_type i) :
            container_reference<M>(m), i_(i),
            v1_(m.data1_[i]), v2_(m.data2_[i]), v3_(m.data3_[i]),
            dirty_(false), is_copy_(false) {}
        BOOST_UBLAS_INLINE
        index_triple(const self_type& rhs) :
            container_reference<M>(rhs()), i_(0),
            v1_(rhs.v1_), v2_(rhs.v2_), v3_(rhs.v3_),
            dirty_(false), is_copy_(true) {}
        BOOST_UBLAS_INLINE
        ~index_triple() {
            if (dirty_ && (!is_copy_) ) {
                (*this)().data1_[i_] = v1_;
                (*this)().data2_[i_] = v2_;
                (*this)().data3_[i_] = v3_;
            }
        }

        BOOST_UBLAS_INLINE
        self_type& operator=(const self_type& rhs) {
            v1_ = rhs.v1_;
            v2_ = rhs.v2_;
            v3_ = rhs.v3_;
            dirty_ = true;
            return *this;
        }

        BOOST_UBLAS_INLINE
        void swap(self_type& rhs) {
            self_type tmp(rhs);
            rhs = *this;
            *this = tmp;
        }

        BOOST_UBLAS_INLINE
        friend void swap(self_type& lhs, self_type& rhs) {
            lhs.swap(rhs);
        }

        friend void swap(self_type lhs, self_type rhs) { // For gcc 4.8 and c++11
            lhs.swap(rhs);
        }

        BOOST_UBLAS_INLINE
        bool equal(const self_type& rhs) const {
            return ((v1_ == rhs.v1_) && (v2_ == rhs.v2_));
        }
        BOOST_UBLAS_INLINE
        bool less(const self_type& rhs) const {
            return ((v1_ < rhs.v1_) ||
                    (v1_ == rhs.v1_ && v2_ < rhs.v2_));
        }
        BOOST_UBLAS_INLINE
        friend bool operator == (const self_type& lhs, const self_type& rhs) {
            return lhs.equal(rhs);
        }
        BOOST_UBLAS_INLINE
        friend bool operator != (const self_type& lhs, const self_type& rhs) {
            return !lhs.equal(rhs);
        }
        BOOST_UBLAS_INLINE
        friend bool operator < (const self_type& lhs, const self_type& rhs) {
            return lhs.less(rhs);
        }
        BOOST_UBLAS_INLINE
        friend bool operator >= (const self_type& lhs, const self_type& rhs) {
            return !lhs.less(rhs);
        }
        BOOST_UBLAS_INLINE
        friend bool operator > (const self_type& lhs, const self_type& rhs) {
            return rhs.less(lhs);
        }
        BOOST_UBLAS_INLINE
        friend bool operator <= (const self_type& lhs, const self_type& rhs) {
            return !rhs.less(lhs);
        }

    private:
        size_type i_;
        typename M::value1_type v1_;
        typename M::value2_type v2_;
        typename M::value3_type v3_;
        bool dirty_;
        bool is_copy_;
    };

    template <class V1, class V2, class V3>
    class index_triple_array:
        private boost::noncopyable {

        typedef index_triple_array<V1, V2, V3> self_type;
    public:
        typedef typename V1::value_type value1_type;
        typedef typename V2::value_type value2_type;
        typedef typename V3::value_type value3_type;

        typedef typename V1::size_type size_type;
        typedef typename V1::difference_type difference_type;
        typedef index_triple<self_type> value_type;
        // There is nothing that can be referenced directly. Always return a copy of the index_triple
        typedef value_type reference;
        typedef const value_type const_reference;

        BOOST_UBLAS_INLINE
        index_triple_array(size_type size, V1& data1, V2& data2, V3& data3) :
              size_(size),data1_(data1),data2_(data2),data3_(data3) {}

        BOOST_UBLAS_INLINE
        size_type size() const {
            return size_;
        }

        BOOST_UBLAS_INLINE
        const_reference operator () (size_type i) const {
            return value_type((*this), i);
        }
        BOOST_UBLAS_INLINE
        reference operator () (size_type i) {
            return value_type((*this), i);
        }

        typedef indexed_iterator<self_type, std::random_access_iterator_tag> iterator;
        typedef indexed_const_iterator<self_type, std::random_access_iterator_tag> const_iterator;

        BOOST_UBLAS_INLINE
        iterator begin() {
            return iterator( (*this), 0);
        }
        BOOST_UBLAS_INLINE
        iterator end() {
            return iterator( (*this), size());
        }

        BOOST_UBLAS_INLINE
        const_iterator begin() const {
            return const_iterator( (*this), 0);
        }
        BOOST_UBLAS_INLINE
        const_iterator cbegin () const {
            return begin ();
        }
        BOOST_UBLAS_INLINE
        const_iterator end() const {
            return const_iterator( (*this), size());
        }
        BOOST_UBLAS_INLINE
        const_iterator cend () const {
            return end ();
        }

        // unnecessary function:
        BOOST_UBLAS_INLINE
        bool equal(size_type i1, size_type i2) const {
            return ((data1_[i1] == data1_[i2]) && (data2_[i1] == data2_[i2]));
        }
        BOOST_UBLAS_INLINE
        bool less(size_type i1, size_type i2) const {
            return ((data1_[i1] < data1_[i2]) ||
                    (data1_[i1] == data1_[i2] && data2_[i1] < data2_[i2]));
        }

        // gives a large speedup
        BOOST_UBLAS_INLINE
        friend void iter_swap(const iterator& lhs, const iterator& rhs) {
            const size_type i1 = lhs.index();
            const size_type i2 = rhs.index();
            std::swap(lhs().data1_[i1], rhs().data1_[i2]);
            std::swap(lhs().data2_[i1], rhs().data2_[i2]);
            std::swap(lhs().data3_[i1], rhs().data3_[i2]);
        }

    private:
        size_type size_;
        V1& data1_;
        V2& data2_;
        V3& data3_;

        // friend class value_type;
        friend class index_triple<self_type>;
    };

}}}

#endif


code:
The _WSJT-X_ packages include program *`rigctl-wsjtx[.exe]`*, which
can be used to send CAT sequences to a rig from the command line, or
from a batch file or shell script; and program *`rigctld-wsjtx[.exe]`*,
which allows other compatible applications to share a CAT connection
to a rig.  These program versions include the latest Hamlib rig
drivers -- the same ones used by _WSJT-X_ itself.

Additional utility programs *`jt4code`*, *`jt9code`*, and *`jt65code`*
let you explore the conversion of user-level messages into channel
symbols or "`tone numbers,`" and back again.  These programs can be
useful to someone designing a beacon generator, for understanding the
permissible structure of transmitted messages, and for studying
behavior of the error-control codes.

Channel-symbol values for JT4 run from 0 to 3.  The total number of
symbols in a transmitted message is 206.  To run `jt4code`, enter the
program name followed by a JT4 message enclosed in quotes.  In Windows
the command and program output might look like this:

 C:\WSJTX\bin> jt4code "G0XYZ K1ABC FN42"
      Message                 Decoded                Err? Type
 -------------------------------------------------------------------
  1.  G0XYZ K1ABC FN42        G0XYZ K1ABC FN42            1: Std Msg

 Channel symbols
  2 0 0 1 3 2 0 2 3 1 0 3 3 2 2 1 2 1 0 0 0 2 0 0 2 1 1 2 0 0
  2 0 2 0 2 0 2 0 2 3 0 3 1 0 3 1 0 3 0 1 1 1 1 1 0 1 0 0 2 3
  2 2 3 0 2 1 3 3 3 3 2 0 2 1 2 3 0 0 2 3 1 1 1 0 3 1 2 0 3 2
  0 2 3 3 0 1 2 1 2 1 0 1 0 1 1 1 1 3 0 3 0 3 2 3 3 0 3 0 1 0
  3 3 3 0 0 3 2 1 3 2 3 1 3 3 2 2 0 2 3 3 2 1 1 0 2 2 3 3 1 2
  3 1 1 2 1 1 1 0 2 1 2 0 2 3 1 2 3 1 2 2 1 2 0 0 3 3 1 1 1 1
  2 0 3 3 0 2 2 2 3 3 0 0 0 1 2 3 3 2 1 1 1 3 2 3 0 3

Channel-symbol values for JT9 run from 0 to 8, with 0 representing the
sync tone.  The total number of symbols in a transmitted message is
85.  Enter the program name followed by a JT9 message enclosed in
quotes:

 C:\WSJTX\bin> jt9code "G0XYZ K1ABC FN42"
      Message                 Decoded                Err? Type
 -------------------------------------------------------------------
  1.  G0XYZ K1ABC FN42        G0XYZ K1ABC FN42            1: Std Msg

 Channel symbols
  0 0 7 3 0 3 2 5 4 0 1 7 7 7 8 0 4 8 8 2 2 1 0 1 1 3 5 4 5 6
  8 7 0 6 0 1 8 3 3 7 8 1 1 2 4 5 8 1 5 2 0 0 8 6 0 5 8 5 1 0
  5 8 7 7 2 0 4 6 6 6 7 6 0 1 8 8 5 7 2 5 1 5 0 4 0

For the corresponding program *`jt65code`* only the
information-carrying channel symbols are shown, and the symbol values
range from 0 to 63.  Sync symbols lie two tone intervals below data
tone 0, and the sequential locations of sync symbols are described in
the <<JT65PRO,JT65 Protocol>> section of this Guide.

A typical execution of `jt65code` is shown below.  The program
displays the packed message of 72 bits, shown here as 12 six-bit
symbol values, followed by the channel symbols:

 C:\WSJTX\bin> jt65code "G0XYZ K1ABC FN42"
      Message                 Decoded                Err? Type
 ----------------------------------------------------------------------
  1.  G0XYZ K1ABC FN42        G0XYZ K1ABC FN42            1:    Std Msg

 Packed message, 6-bit symbols  61 36 45 30  3 55  3  2 14  5 33 40

 Information-carrying channel symbols
    56 40  8 40 51 47 50 34 44 53 22 53 28 31 13 60 46  2 14 58 43
    41 58 35  8 35  3 24  1 21 41 43  0 25 54  9 41 54  7 25 21  9
    62 59  7 43 31 21 57 13 59 41 17 49 19 54 21 39 33 42 18  2 60

For an illustration of the power of the strong error-control coding in
JT9 and JT65, try looking at the channel symbols after changing a
single character in the message.  For example, change the grid locator
from FN42 to FN43 in the JT65 message:

 C:\WSJTX\bin> jt65code "G0XYZ K1ABC FN43"
      Message                 Decoded                Err? Type
 ----------------------------------------------------------------------
  1.  G0XYZ K1ABC FN43        G0XYZ K1ABC FN43            1:    Std Msg

 Packed message, 6-bit symbols  61 36 45 30  3 55  3  2 14  5 33 41

 Information-carrying channel symbols
    25 35 47  8 13  9 61 40 44  9 51  6  8 40 38 34  8  2 21 23 30
    51 32 56 39 35  3 50 48 30  8  5 40 18 54  9 24 30 26 61 23 11
     3 59  7  7 39  1 25 24  4 50 17 49 52 19 34  7  4 34 61  2 61

You will discover that every possible JT65 message differs from every
other possible JT65 message in at least 52 of the 63
information-carrying channel symbols.

Here's an example using the QRA64 mode:

 C:\WSJTX\bin qra64code "KA1ABC WB9XYZ EN37"
      Message                 Decoded                Err? Type
 --------------------------------------------------------------------------
   1 KA1ABC WB9XYZ EN37      KA1ABC WB9XYZ EN37          1:    Std Msg

 Packed message, 6-bit symbols  34 16 49 32 51 26 31 40 41 22  0 41

 Information-carrying channel symbols
   34 16 49 32 51 26 31 40 41 22  0 41 16 46 14 24 58 45 22 45 38 54  7 23  2 49 32 50 20 33
   55 51  7 31 31 46 41 25 55 14 62 33 29 24  2 49  4 38 15 21  1 41 56 56 16 44 17 30 46 36
   23 23 41

 Channel symbols including sync
   20 50 60  0 40 10 30 34 16 49 32 51 26 31 40 41 22  0 41 16 46 14 24 58 45 22 45 38 54  7
   23  2 49 32 50 20 33 55 51 20 50 60  0 40 10 30  7 31 31 46 41 25 55 14 62 33 29 24  2 49
    4 38 15 21  1 41 56 56 16 44 17 30 46 36 23 23 41 20 50 60  0 40 10 30

Execution of any of these utility programs with "-t" as the only
command-line argument produces examples of all supported message
types.  For example, using `jt65code -t`:

 C:\WSJTX\bin> jt65code -t

      Message                 Decoded                Err? Type
 --------------------------------------------------------------------------
  1.  CQ WB9XYZ EN34          CQ WB9XYZ EN34              1:    Std Msg
  2.  CQ DX WB9XYZ EN34       CQ DX WB9XYZ EN34           1:    Std Msg
  3.  QRZ WB9XYZ EN34         QRZ WB9XYZ EN34             1:    Std Msg
  4.  KA1ABC WB9XYZ EN34      KA1ABC WB9XYZ EN34          1:    Std Msg
  5.  KA1ABC WB9XYZ RO        KA1ABC WB9XYZ RO            1:    Std Msg
  6.  KA1ABC WB9XYZ -21       KA1ABC WB9XYZ -21           1:    Std Msg
  7.  KA1ABC WB9XYZ R-19      KA1ABC WB9XYZ R-19          1:    Std Msg
  8.  KA1ABC WB9XYZ RRR       KA1ABC WB9XYZ RRR           1:    Std Msg
  9.  KA1ABC WB9XYZ 73        KA1ABC WB9XYZ 73            1:    Std Msg
 10.  KA1ABC WB9XYZ           KA1ABC WB9XYZ               1:    Std Msg
 11.  CQ 000 WB9XYZ EN34      CQ 000 WB9XYZ EN34          1:    Std Msg
 12.  CQ 999 WB9XYZ EN34      CQ 999 WB9XYZ EN34          1:    Std Msg
 13.  CQ EU WB9XYZ EN34       CQ EU WB9XYZ EN34           1:    Std Msg
 14.  CQ WY WB9XYZ EN34       CQ WY WB9XYZ EN34           1:    Std Msg
 15.  ZL/KA1ABC WB9XYZ        ZL/KA1ABC WB9XYZ            2:    Type 1 pfx
 16.  KA1ABC ZL/WB9XYZ        KA1ABC ZL/WB9XYZ            2:    Type 1 pfx
 17.  KA1ABC/4 WB9XYZ         KA1ABC/4 WB9XYZ             3:    Type 1 sfx
 18.  KA1ABC WB9XYZ/4         KA1ABC WB9XYZ/4             3:    Type 1 sfx
 19.  CQ ZL4/KA1ABC           CQ ZL4/KA1ABC               4:    Type 2 pfx
 20.  DE ZL4/KA1ABC           DE ZL4/KA1ABC               4:    Type 2 pfx
 21.  QRZ ZL4/KA1ABC          QRZ ZL4/KA1ABC              4:    Type 2 pfx
 22.  CQ WB9XYZ/VE4           CQ WB9XYZ/VE4               5:    Type 2 sfx
 23.  HELLO WORLD             HELLO WORLD                 6:    Free text
 24.  ZL4/KA1ABC 73           ZL4/KA1ABC 73               6:    Free text
 25.  KA1ABC XL/WB9XYZ        KA1ABC XL/WB9            *  6:    Free text
 26.  KA1ABC WB9XYZ/W4        KA1ABC WB9XYZ            *  6:    Free text
 27.  123456789ABCDEFGH       123456789ABCD            *  6:    Free text
 28.  KA1ABC WB9XYZ EN34 OOO  KA1ABC WB9XYZ EN34 OOO      1:    Std Msg
 29.  KA1ABC WB9XYZ OOO       KA1ABC WB9XYZ OOO           1:    Std Msg
 30.  RO                      RO                         -1:    Shorthand
 31.  RRR                     RRR                        -1:    Shorthand
 32.  73                      73                         -1:    Shorthand

MSK144 uses a binary channel code, so transmitted symbols have the value
0 or 1.  Even numbered symbols (index starting at 0) are transmitted on
the I (in-phase) channel, odd numbered symbols on the Q (quadrature)
channel.  A typical execution of `msk144code` is shown below.

 C:\WSJTX\bin> msk144code "K1ABC W9XYZ EN37"

      Message                 Decoded                Err? Type
 --------------------------------------------------------------------------
  1.  K1ABC W9XYZ EN37        K1ABC W9XYZ EN37            1: Std Msg

 Channel symbols
 110000100011001101010101001000111111001001001100110010011100001001000000
 010110001011101111001010111011001100110101011000111101100010111100100011

 C:\WSJTX\bin> msk144code "<KA1ABC WB9XYZ> R-03"
      Message                 Decoded                Err? Type
 --------------------------------------------------------------------------
  1.  <KA1ABC WB9XYZ> R-03    <KA1ABC WB9XYZ> R-03        7: Hashed calls

 Channel symbols
 1000011100001000111011111010011011111010

license: mit


code:
/*
 [auto_generated]
 boost/numeric/odeint/algebra/detail/macros.hpp

 [begin_description]
 Some macros for type checking.
 [end_description]

 Copyright 2010-2012 Karsten Ahnert
 Copyright 2010 Mario Mulansky

 Distributed under the Boost Software License, Version 1.0.
 (See accompanying file LICENSE_1_0.txt or
 copy at http://www.boost.org/LICENSE_1_0.txt)
 */

#ifndef BOOST_NUMERIC_ODEINT_ALGEBRA_DETAIL_MACROS_HPP_INCLUDED
#define BOOST_NUMERIC_ODEINT_ALGEBRA_DETAIL_MACROS_HPP_INCLUDED

//type traits aren't working with nvcc
#ifndef __CUDACC__
#include <boost/type_traits.hpp>
#include <boost/static_assert.hpp>

#define BOOST_ODEINT_CHECK_CONTAINER_TYPE( Type1 , Type2 ) \
        BOOST_STATIC_ASSERT(( boost::is_same< typename boost::remove_const< Type1 >::type , Type2 >::value ))

#else
//empty macro for nvcc
#define BOOST_ODEINT_CHECK_CONTAINER_TYPE( Type1 , Type2 )

#endif // __CUDACC__

/*
#define BOOST_ODEINT_CHECK_OPERATION_ARITY( Operation , Arity ) \
        BOOST_STATIC_ASSERT(( boost::function_traits< Operation >::arity == Arity ))
 */

#endif // BOOST_NUMERIC_ODEINT_ALGEBRA_DETAIL_MACROS_HPP_INCLUDED


code:
//  (C) Copyright John Maddock 2007.
//  Use, modification and distribution are subject to the
//  Boost Software License, Version 1.0. (See accompanying file
//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
//  This file is machine generated, do not edit by hand

// Polynomial evaluation using Horners rule
#ifndef BOOST_MATH_TOOLS_POLY_RAT_14_HPP
#define BOOST_MATH_TOOLS_POLY_RAT_14_HPP

namespace boost{ namespace math{ namespace tools{ namespace detail{

template <class T, class U, class V>
inline V evaluate_rational_c_imp(const T*, const U*, const V&, const mpl::int_<0>*) BOOST_MATH_NOEXCEPT(V)
{
   return static_cast<V>(0);
}

template <class T, class U, class V>
inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const mpl::int_<1>*) BOOST_MATH_NOEXCEPT(V)
{
   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
}

template <class T, class U, class V>
inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const mpl::int_<2>*) BOOST_MATH_NOEXCEPT(V)
{
   if(x <= 1)
     return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
   else
   {
      V z = 1 / x;
      return static_cast<V>((a[0] * z + a[1]) / (b[0] * z + b[1]));
   }
}

template <class T, class U, class V>
inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const mpl::int_<3>*) BOOST_MATH_NOEXCEPT(V)
{
   if(x <= 1)
     return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
   else
   {
      V z = 1 / x;
      return static_cast<V>(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2]));
   }
}

template <class T, class U, class V>
inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const mpl::int_<4>*) BOOST_MATH_NOEXCEPT(V)
{
   if(x <= 1)
     return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
   else
   {
      V z = 1 / x;
      return static_cast<V>((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3]));
   }
}

template <class T, class U, class V>
inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const mpl::int_<5>*) BOOST_MATH_NOEXCEPT(V)
{
   if(x <= 1)
     return static_cast<V>(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
   else
   {
      V z = 1 / x;
      return static_cast<V>(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]));
   }
}

template <class T, class U, class V>
inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const mpl::int_<6>*) BOOST_MATH_NOEXCEPT(V)
{
   if(x <= 1)
     return static_cast<V>((((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((b[5] * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
   else
   {
      V z = 1 / x;
      return static_cast<V>((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) / (((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]));
   }
}

template <class T, class U, class V>
inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const mpl::int_<7>*) BOOST_MATH_NOEXCEPT(V)
{
   if(x <= 1)
     return static_cast<V>(((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((b[6] * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
   else
   {
      V z = 1 / x;
      return static_cast<V>(((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) / ((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]));
   }
}

template <class T, class U, class V>
inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const mpl::int_<8>*) BOOST_MATH_NOEXCEPT(V)
{
   if(x <= 1)
     return static_cast<V>((((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((b[7] * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
   else
   {
      V z = 1 / x;
      return static_cast<V>((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) / (((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]));
   }
}

template <class T, class U, class V>
inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const mpl::int_<9>*) BOOST_MATH_NOEXCEPT(V)
{
   if(x <= 1)
     return static_cast<V>(((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((b[8] * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
   else
   {
      V z = 1 / x;
      return static_cast<V>(((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) / ((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]));
   }
}

template <class T, class U, class V>
inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const mpl::int_<10>*) BOOST_MATH_NOEXCEPT(V)
{
   if(x <= 1)
     return static_cast<V>((((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((b[9] * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
   else
   {
      V z = 1 / x;
      return static_cast<V>((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) / (((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]));
   }
}

template <class T, class U, class V>
inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const mpl::int_<11>*) BOOST_MATH_NOEXCEPT(V)
{
   if(x <= 1)
     return static_cast<V>(((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((b[10] * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
   else
   {
      V z = 1 / x;
      return static_cast<V>(((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) / ((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]));
   }
}

template <class T, class U, class V>
inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const mpl::int_<12>*) BOOST_MATH_NOEXCEPT(V)
{
   if(x <= 1)
     return static_cast<V>((((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((b[11] * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
   else
   {
      V z = 1 / x;
      return static_cast<V>((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) / (((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]));
   }
}

template <class T, class U, class V>
inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const mpl::int_<13>*) BOOST_MATH_NOEXCEPT(V)
{
   if(x <= 1)
     return static_cast<V>(((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((b[12] * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
   else
   {
      V z = 1 / x;
      return static_cast<V>(((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) / ((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]));
   }
}

template <class T, class U, class V>
inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const mpl::int_<14>*) BOOST_MATH_NOEXCEPT(V)
{
   if(x <= 1)
     return static_cast<V>((((((((((((((a[13] * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((b[13] * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
   else
   {
      V z = 1 / x;
      return static_cast<V>((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) / (((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]));
   }
}

}}}} // namespaces

#endif // include guard


code:
// Copyright 2006 Roland Schwarz.
// (C) Copyright 2007 Anthony Williams
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// This work is a reimplementation along the design and ideas
// of William E. Kempf.

#ifndef BOOST_THREAD_RS06040501_HPP
#define BOOST_THREAD_RS06040501_HPP

// fetch compiler and platform configuration
#include <boost/config.hpp>

// insist on threading support being available:
#include <boost/config/requires_threads.hpp>

// choose platform
#if defined(linux) || defined(__linux) || defined(__linux__)
#  define BOOST_THREAD_LINUX
//#  define BOOST_THREAD_WAIT_BUG boost::posix_time::microseconds(100000)
#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
#  define BOOST_THREAD_BSD
#elif defined(sun) || defined(__sun)
#  define BOOST_THREAD_SOLARIS
#elif defined(__sgi)
#  define BOOST_THREAD_IRIX
#elif defined(__hpux)
#  define BOOST_THREAD_HPUX
#elif defined(__CYGWIN__)
#  define BOOST_THREAD_CYGWIN
#elif (defined(_WIN32) || defined(__WIN32__) || defined(WIN32)) && !defined(BOOST_DISABLE_WIN32)
#  define BOOST_THREAD_WIN32
#elif defined(__BEOS__)
#  define BOOST_THREAD_BEOS
#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
#  define BOOST_THREAD_MACOS
//#  define BOOST_THREAD_WAIT_BUG boost::posix_time::microseconds(1000)
#elif defined(__IBMCPP__) || defined(_AIX)
#  define BOOST_THREAD_AIX
#elif defined(__amigaos__)
#  define BOOST_THREAD_AMIGAOS
#elif defined(__QNXNTO__)
#  define BOOST_THREAD_QNXNTO
#elif defined(unix) || defined(__unix) || defined(_XOPEN_SOURCE) || defined(_POSIX_SOURCE)
#       if defined(BOOST_HAS_PTHREADS) && !defined(BOOST_THREAD_POSIX)
#               define BOOST_THREAD_POSIX
#       endif
#endif

// For every supported platform add a new entry into the dispatch table below.
// BOOST_THREAD_POSIX is tested first, so on platforms where posix and native
// threading is available, the user may choose, by defining BOOST_THREAD_POSIX
// in her source. If a platform is known to support pthreads and no native
// port of boost_thread is available just specify "pthread" in the
// dispatcher table. If there is no entry for a platform but pthreads is
// available on the platform, pthread is choosen as default. If nothing is
// available the preprocessor will fail with a diagnostic message.

#if defined(BOOST_THREAD_POSIX)
#  define BOOST_THREAD_PLATFORM_PTHREAD
#else
#  if defined(BOOST_THREAD_WIN32)
#       define BOOST_THREAD_PLATFORM_WIN32
#  elif defined(BOOST_HAS_PTHREADS)
#       define BOOST_THREAD_PLATFORM_PTHREAD
#  else
#       error "Sorry, no boost threads are available for this platform."
#  endif
#endif

#endif // BOOST_THREAD_RS06040501_HPP


code:
/*=============================================================================
    Copyright (c) 2001-2011 Joel de Guzman

    Distributed under the Boost Software License, Version 1.0. (See accompanying
    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(FUSION_ADVANCE_09172005_1149)
#define FUSION_ADVANCE_09172005_1149

#include <boost/fusion/support/config.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/fusion/iterator/next.hpp>
#include <boost/fusion/iterator/prior.hpp>

namespace boost { namespace fusion { namespace advance_detail
{
    // Default advance implementation, perform next(i)
    // or prior(i) N times.

    template <typename Iterator, int N>
    struct forward;

    template <typename Iterator, int N>
    struct next_forward
    {
        typedef typename
            forward<
                typename result_of::next<Iterator>::type
              , N-1
            >::type
        type;
    };

    template <typename Iterator, int N>
    struct forward
    {
        typedef typename
            mpl::eval_if_c<
                (N == 0)
              , mpl::identity<Iterator>
              , next_forward<Iterator, N>
            >::type
        type;

        BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
        static type const&
        call(type const& i)
        {
            return i;
        }

        template <typename I>
        BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
        static type
        call(I const& i)
        {
            return call(fusion::next(i));
        }
    };

    template <typename Iterator, int N>
    struct backward;

    template <typename Iterator, int N>
    struct next_backward
    {
        typedef typename
            backward<
                typename result_of::prior<Iterator>::type
              , N+1
            >::type
        type;
    };

    template <typename Iterator, int N>
    struct backward
    {
        typedef typename
            mpl::eval_if_c<
                (N == 0)
              , mpl::identity<Iterator>
              , next_backward<Iterator, N>
            >::type
        type;

        BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
        static type const&
        call(type const& i)
        {
            return i;
        }

        template <typename I>
        BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
        static type
        call(I const& i)
        {
            return call(fusion::prior(i));
        }
    };

}}}

#endif


code:
//  Copyright Neil Groves 2009. Use, modification and
//  distribution is subject to the Boost Software License, Version
//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//
//
// For more information, see http://www.boost.org/libs/range/
//
#ifndef BOOST_RANGE_ALGORITHM_PARTIAL_SORT_HPP_INCLUDED
#define BOOST_RANGE_ALGORITHM_PARTIAL_SORT_HPP_INCLUDED

#include <boost/concept_check.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/range/concepts.hpp>
#include <algorithm>

namespace boost
{
    namespace range
    {

/// \brief template function partial_sort
///
/// range-based version of the partial_sort std algorithm
///
/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
template<class RandomAccessRange>
inline RandomAccessRange& partial_sort(RandomAccessRange& rng,
    BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type middle)
{
    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
    std::partial_sort(boost::begin(rng), middle, boost::end(rng));
    return rng;
}

/// \overload
template<class RandomAccessRange>
inline const RandomAccessRange& partial_sort(const RandomAccessRange& rng,
    BOOST_DEDUCED_TYPENAME range_iterator<const RandomAccessRange>::type middle)
{
    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
    std::partial_sort(boost::begin(rng), middle, boost::end(rng));
    return rng;
}

/// \overload
template<class RandomAccessRange, class BinaryPredicate>
inline RandomAccessRange& partial_sort(RandomAccessRange& rng,
    BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type middle,
    BinaryPredicate sort_pred)
{
    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
    std::partial_sort(boost::begin(rng), middle, boost::end(rng),
                        sort_pred);
    return rng;
}

/// \overload
template<class RandomAccessRange, class BinaryPredicate>
inline const RandomAccessRange& partial_sort(const RandomAccessRange& rng,
    BOOST_DEDUCED_TYPENAME range_iterator<const RandomAccessRange>::type middle,
    BinaryPredicate sort_pred)
{
    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
    std::partial_sort(boost::begin(rng), middle, boost::end(rng),
                        sort_pred);
    return rng;
}

    } // namespace range
    using range::partial_sort;
} // namespace boost

#endif // include guard