This project is a demonstrator tool, made by the MOISE project, that translates timed Altarica models into Fiacre models. Such translation allows to use model checkers such as Tina to prove properties. The project contains the translator tool.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

210 lines
5.7 KiB

//
// Copyright (c) 2009 Rutger ter Borg
//
// 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_BINDINGS_STRIDE_HPP
#define BOOST_NUMERIC_BINDINGS_STRIDE_HPP
#include <boost/numeric/bindings/size.hpp>
#include <boost/mpl/min.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/less_equal.hpp>
#include <boost/mpl/equal_to.hpp>
#include <boost/mpl/range_c.hpp>
#include <boost/mpl/times.hpp>
#include <boost/mpl/greater.hpp>
#include <boost/mpl/plus.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/static_assert.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace detail {
template< typename T, typename AddressingIndex, typename Enable = void >
struct stride_impl {
typedef tag::stride_type< AddressingIndex::value > key_type;
typedef typename result_of_get< T, key_type >::type result_type;
static result_type invoke( const T& t ) {
return get< key_type >( t );
}
};
//
// Strides for ranks outside the scope of the object are fixed at
// the dot product of its existing sizes and strides.
//
// Object rank result of strideN(), with N > rank
// scalar 0 1
// vector 1 size1 * stride1
// matrix 2 size1 * stride1 + size2 * stride2
// tensor N sum_i( size_i, stride_i ) (dot( size, stride))
//
// Iff size_i and stride_i are integral constants, results will be known at
// compile time. Otherwise, the result_type will be std::ptrdiff_t.
//
template< typename T, typename AddressingIndex >
struct stride_impl< T, AddressingIndex,
typename boost::enable_if<
mpl::equal_to< rank<T>, tag::scalar >
>::type > {
typedef typename mpl::int_<1> result_type;
static result_type invoke( const T& t ) {
return result_type();
}
};
template< typename T, typename State, typename AddressingIndex >
struct fold_stride_size {
typedef tag::addressing_index< AddressingIndex::value > index_type;
typedef typename result_of::size< T, index_type >::type size_type;
typedef typename stride_impl< T, index_type >::result_type stride_type;
typedef typename mpl::if_<
mpl::or_<
is_same< State, std::ptrdiff_t >,
is_same< size_type, std::ptrdiff_t >,
is_same< stride_type, std::ptrdiff_t >
>,
std::ptrdiff_t,
mpl::plus<
State,
mpl::times<
size_type,
stride_type
>
>
>::type type;
};
//
// If Result isn't a ptrdiff_t, just invoke the integral constant
// and return that. Otherwise, runtime stuff is involved, so we'll
// have to evaluate sum_i( size_i, stride_i ).
//
template< typename T, typename Result, int AddressingIndex >
struct apply_fold {
static Result invoke( const T& t ) {
return Result();
}
};
template< typename T, int AddressingIndex >
struct apply_fold< T, std::ptrdiff_t, AddressingIndex > {
static std::ptrdiff_t invoke( const T& t ) {
return size( t, tag::addressing_index< AddressingIndex >() ) *
stride_impl< T, tag::addressing_index< AddressingIndex > >::invoke( t ) +
apply_fold< T, std::ptrdiff_t, AddressingIndex-1 >::invoke( t );
}
};
template< typename T >
struct apply_fold< T, std::ptrdiff_t, 0 > {
static std::ptrdiff_t invoke( const T& ) {
return 0;
}
};
// Could be made generic for dimensions > 2,
// but not enough time right now
template< typename T, typename AddressingIndex >
struct stride_impl< T, AddressingIndex,
typename boost::enable_if<
mpl::and_<
mpl::greater< rank<T>, tag::scalar >,
mpl::greater< AddressingIndex, rank<T> >
>
>::type > {
typedef mpl::range_c< int, 1, rank<T>::value+1 > index_range;
typedef typename mpl::fold<
index_range,
mpl::int_< 0 >,
fold_stride_size<
T,
mpl::_1,
mpl::_2
>
>::type result_type;
static result_type invoke( const T& t ) {
return apply_fold< T, result_type, rank<T>::value >::invoke( t );
}
};
} // namespace detail
namespace result_of {
template< typename T, typename Tag = tag::addressing_index<1> >
struct stride {
BOOST_STATIC_ASSERT( (is_tag<Tag>::value) );
typedef typename detail::stride_impl< T, Tag >::result_type type;
};
} // namespace result_of
//
// Overloads for free template functions stride( x, tag ),
//
template< typename T, typename Tag >
inline typename result_of::stride< const T, Tag >::type
stride( const T& t, Tag ) {
return detail::stride_impl< const T, Tag >::invoke( t );
}
// Overloads for free template functions stride( x )
// Valid for types with rank <= 1 (scalars, vectors)
// In theory, we could provide overloads for matrices here, too,
// if their minimal_rank is at most 1.
template< typename T >
inline typename
boost::enable_if<
mpl::less< rank<T>, mpl::int_<2> >,
typename result_of::stride< const T, tag::addressing_index<1> >::type
>::type
stride( const T& t ) {
return detail::stride_impl<const T, tag::addressing_index<1> >::invoke( t );
}
#define GENERATE_STRIDE_INDEX( z, which, unused ) \
GENERATE_FUNCTIONS( stride, which, tag::addressing_index<which> )
BOOST_PP_REPEAT_FROM_TO(1,3,GENERATE_STRIDE_INDEX,~)
GENERATE_FUNCTIONS( stride, _row, tag::addressing_index<1> )
GENERATE_FUNCTIONS( stride, _column, tag::addressing_index<2> )
GENERATE_FUNCTIONS( stride, _major, typename addressing_index_major<T>::type )
GENERATE_FUNCTIONS( stride, _minor, typename addressing_index_minor<T>::type )
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif