126 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			126 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| // Copyright 2002 The Trustees of Indiana University.
 | |
| 
 | |
| // 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)
 | |
| 
 | |
| //  Boost.MultiArray Library
 | |
| //  Authors: Ronald Garcia
 | |
| //           Jeremy Siek
 | |
| //           Andrew Lumsdaine
 | |
| //  See http://www.boost.org/libs/multi_array for documentation.
 | |
| 
 | |
| #ifndef BOOST_STORAGE_ORDER_RG071801_HPP
 | |
| #define BOOST_STORAGE_ORDER_RG071801_HPP
 | |
| 
 | |
| #include "boost/multi_array/types.hpp"
 | |
| #include "boost/array.hpp"
 | |
| #include "boost/multi_array/algorithm.hpp"
 | |
| #include <algorithm>
 | |
| #include <cstddef>
 | |
| #include <functional>
 | |
| #include <numeric>
 | |
| #include <vector>
 | |
| 
 | |
| namespace boost {
 | |
| 
 | |
|   // RG - This is to make things work with VC++. So sad, so sad.
 | |
|   class c_storage_order; 
 | |
|   class fortran_storage_order;
 | |
| 
 | |
|   template <std::size_t NumDims>
 | |
|   class general_storage_order
 | |
|   {
 | |
|   public:
 | |
|     typedef detail::multi_array::size_type size_type;
 | |
|     template <typename OrderingIter, typename AscendingIter>
 | |
|     general_storage_order(OrderingIter ordering,
 | |
|                           AscendingIter ascending) {
 | |
|       boost::detail::multi_array::copy_n(ordering,NumDims,ordering_.begin());
 | |
|       boost::detail::multi_array::copy_n(ascending,NumDims,ascending_.begin());
 | |
|     }
 | |
| 
 | |
|     // RG - ideally these would not be necessary, but some compilers
 | |
|     // don't like template conversion operators.  I suspect that not
 | |
|     // too many folk will feel the need to use customized
 | |
|     // storage_order objects, I sacrifice that feature for compiler support.
 | |
|     general_storage_order(const c_storage_order&) {
 | |
|       for (size_type i=0; i != NumDims; ++i) {
 | |
|         ordering_[i] = NumDims - 1 - i;
 | |
|       }
 | |
|       ascending_.assign(true);
 | |
|     }
 | |
| 
 | |
|     general_storage_order(const fortran_storage_order&) {
 | |
|       for (size_type i=0; i != NumDims; ++i) {
 | |
|         ordering_[i] = i;
 | |
|       }
 | |
|       ascending_.assign(true);
 | |
|     }
 | |
| 
 | |
|     size_type ordering(size_type dim) const { return ordering_[dim]; }
 | |
|     bool ascending(size_type dim) const { return ascending_[dim]; }
 | |
| 
 | |
|     bool all_dims_ascending() const {
 | |
|       return std::accumulate(ascending_.begin(),ascending_.end(),true,
 | |
|                       std::logical_and<bool>());
 | |
|     }
 | |
| 
 | |
|     bool operator==(general_storage_order const& rhs) const {
 | |
|       return (ordering_ == rhs.ordering_) &&
 | |
|         (ascending_ == rhs.ascending_);
 | |
|     }
 | |
| 
 | |
|   protected:
 | |
|     boost::array<size_type,NumDims> ordering_;
 | |
|     boost::array<bool,NumDims> ascending_;
 | |
|   };
 | |
| 
 | |
|   class c_storage_order 
 | |
|   {
 | |
|     typedef detail::multi_array::size_type size_type;
 | |
|   public:
 | |
|     // This is the idiom for creating your own custom storage orders.
 | |
|     // Not supported by all compilers though!
 | |
| #ifndef __MWERKS__ // Metrowerks screams "ambiguity!"
 | |
|     template <std::size_t NumDims>
 | |
|     operator general_storage_order<NumDims>() const {
 | |
|       boost::array<size_type,NumDims> ordering;
 | |
|       boost::array<bool,NumDims> ascending;
 | |
| 
 | |
|       for (size_type i=0; i != NumDims; ++i) {
 | |
|         ordering[i] = NumDims - 1 - i;
 | |
|         ascending[i] = true;
 | |
|       }
 | |
|       return general_storage_order<NumDims>(ordering.begin(),
 | |
|                                             ascending.begin());
 | |
|     }
 | |
| #endif
 | |
|   };
 | |
| 
 | |
|   class fortran_storage_order
 | |
|   {
 | |
|     typedef detail::multi_array::size_type size_type;
 | |
|   public:
 | |
|     // This is the idiom for creating your own custom storage orders.
 | |
|     // Not supported by all compilers though! 
 | |
| #ifndef __MWERKS__ // Metrowerks screams "ambiguity!"
 | |
|     template <std::size_t NumDims>
 | |
|     operator general_storage_order<NumDims>() const {
 | |
|       boost::array<size_type,NumDims> ordering;
 | |
|       boost::array<bool,NumDims> ascending;
 | |
| 
 | |
|       for (size_type i=0; i != NumDims; ++i) {
 | |
|         ordering[i] = i;
 | |
|         ascending[i] = true;
 | |
|       }
 | |
|       return general_storage_order<NumDims>(ordering.begin(),
 | |
|                                             ascending.begin());
 | |
|     }
 | |
| #endif
 | |
|   };
 | |
| 
 | |
| } // namespace boost
 | |
| 
 | |
| #endif // BOOST_ARRAY_STORAGE_RG071801_HPP
 | 
