File: vsip/impl/adjust-layout.hpp
    1| /* Copyright (c) 2006 by CodeSourcery, LLC.  All rights reserved. */
    2| 
    3| /** @file    vsip/impl/adjust-layout.hpp
    4|     @author  Jules Bergmann
    5|     @date    2006-02-02
    6|     @brief   VSIPL++ Library: Utilities to adjust layout policies.
    7| */
    8| 
    9| #ifndef VSIP_IMPL_ADJUST_LAYOUT_HPP
   10| #define VSIP_IMPL_ADJUST_LAYOUT_HPP
   11| 
   12| /***********************************************************************
   13|   Included Files
   14| ***********************************************************************/
   15| 
   16| #include <vsip/impl/layout.hpp>
   17| 
   18| 
   19| 
   20| /***********************************************************************
   21|   Definitions
   22| ***********************************************************************/
   23| 
   24| namespace vsip
   25| {
   26| 
   27| namespace impl
   28| {
   29| 
   30| /// Adjust a type.  If a preferred type is given, use that.  Otherwise
   31| /// if 'Any_type' is given, use the actual type.
   32| 
   33| /// Provides:
   34| ///  - type  - typedef with the adjusted type.
   35| ///  - equiv - bool set to true if the preferred and actual types
   36| ///            were equivalent (either the same, or preferred was
   37| ///            'Any_type').
   38| 
   39| template <typename PreferredT,
   40|           typename ActualT>
   41| struct Adjust_type
   42| {
   43|   typedef PreferredT type;
   44|   static bool const equiv = false;
   45| };
   46| 
   47| template <typename ActualT>
   48| struct Adjust_type<Any_type, ActualT>
   49| {
   50|   typedef ActualT type;
   51|   static bool const equiv = true;
   52| };
   53| 
   54| template <typename SameT>
   55| struct Adjust_type<SameT, SameT>
   56| {
   57|   typedef SameT type;
   58|   static bool const equiv = true;
   59| };
   60| 
   61| 
   62| 
   63| /// Variant of Adjust_type for adjusting pack_type's.
   64| 
   65| /// In particular, adjusts Stride_unknown pack types to something that
   66| /// can be used to allocate a block.
   67| 
   68| template <typename PreferredT,
   69|           typename ActualT>
   70| struct Adjust_pack_type
   71|   Adjust_type<PreferredT, ActualT>
   72| {};
   73| 
   74| template <>
   75| struct Adjust_pack_type<Any_type, Stride_unknown>
   76| {
   77|   typedef Stride_unit_dense type;
   78|   static bool const equiv = true;
   79| };
   80| 
   81| 
   82| 
   83| /// Variant of Adjust_type for adjusting complex_type's.
   84| 
   85| /// Uses the value type T to determine when the complex_type matters.
   86| /// In particular, for non-complex value types, the complex_type is
   87| /// not applicable.
   88| 
   89| template <typename T,
   90|           typename PreferredT,
   91|           typename ActualT>
   92| struct Adjust_complex_type
   93| {
   94|   typedef ActualT type;
   95|   static bool const equiv = true;
   96| };
   97| 
   98| template <typename T,
   99|           typename PreferredT,
  100|           typename ActualT>
  101| struct Adjust_complex_type<complex<T>, PreferredT, ActualT>
  102|   Adjust_type<PreferredT, ActualT>
  103| {};
  104| 
  105| 
  106| 
  107| /// Adjust an actual layout policy against a required layout policy.
  108| 
  109| /// The resulting layout takes its values from the required layout
  110| /// where it specifies a value, or from the actual layout when the
  111| /// required layout specifies 'Any_type'.
  112| 
  113| template <typename T,
  114|           typename RequiredLP,
  115|           typename ActualLP>
  116| struct Adjust_layout
  117| {
  118|   static dimension_type const dim = RequiredLP::dim;
  119| 
  120|   typedef typename RequiredLP::order_type   req_order_t;
  121|   typedef typename RequiredLP::pack_type    req_pack_t;
  122|   typedef typename RequiredLP::complex_type req_complex_t;
  123| 
  124|   typedef typename ActualLP::order_type     act_order_t;
  125|   typedef typename ActualLP::pack_type      act_pack_t;
  126|   typedef typename ActualLP::complex_type   act_complex_t;
  127| 
  128|   typedef typename Adjust_type<req_order_t,     act_order_t>::type order_type;
  129|   typedef typename Adjust_pack_type<req_pack_t, act_pack_t>::type  pack_type;
  130| 
  131|   typedef typename Adjust_complex_type<T, req_complex_t, act_complex_t>::type
  132|                complex_type;
  133| 
  134|   typedef Layout<dim, order_type, pack_type, complex_type> type;
  135| };
  136| 
  137| 
  138| 
  139| template <dimension_type NewDim,
  140|           typename       LP>
  141| struct Adjust_layout_dim
  142| {
  143|   typedef typename LP::order_type     order_type;
  144|   typedef typename LP::pack_type      pack_type;
  145|   typedef typename LP::complex_type   complex_type;
  146| 
  147|   typedef Layout<NewDim, order_type, pack_type, complex_type> type;
  148| };
  149| 
  150| 
  151| 
  152| template <typename NewPackType,
  153|           typename LP>
  154| struct Adjust_layout_pack
  155| {
  156|   typedef typename LP::order_type     order_type;
  157|   typedef typename LP::pack_type      pack_type;
  158|   typedef typename LP::complex_type   complex_type;
  159| 
  160|   typedef Layout<LP::dim, order_type, NewPackType, complex_type> type;
  161| };
  162| 
  163| 
  164| 
  165| // Determine if an given layout policy is compatible with a required
  166| // layout policy.
  167| 
  168| // The value_type 'T' is used to determine when differences between
  169| // complex_type matter.
  170| 
  171| template <typename T,
  172|           typename RequiredLP,
  173|           typename ActualLP>
  174| struct Is_layout_compatible
  175| {
  176|   typedef typename RequiredLP::order_type   req_order_type;
  177|   typedef typename RequiredLP::pack_type    req_pack_type;
  178|   typedef typename RequiredLP::complex_type req_complex_type;
  179| 
  180|   typedef typename ActualLP::order_type     act_order_type;
  181|   typedef typename ActualLP::pack_type      act_pack_type;
  182|   typedef typename ActualLP::complex_type   act_complex_type;
  183| 
  184|   static bool const value =
  185|     RequiredLP::dim == ActualLP::dim                     &&
  186|     Adjust_type<           req_order_type,   act_order_type>::equiv &&
  187|     Adjust_pack_type<      req_pack_type,    act_pack_type>::equiv  &&
  188|     Adjust_complex_type<T, req_complex_type, act_complex_type>::equiv;
  189| };
  190| 
  191| // namespace vsip::impl
  192| // namespace vsip
  193| 
  194| #endif // VSIP_IMPL_ADJUST_LAYOUT_HPP