Implementation Details

| Home | Libraries | People | FAQ | More

### Implementation Details

### Introduction

The implementation has depended on close study of the existing code of FC++. The FC++ List Implementation is a carefully crafted code which allows for efficient processing of a number of different cases. In particular it makes use of the FC++ Reuser Implementation for processing of repetitive evaluations.

FC++ uses a combination of polymorphic and single type functions which can be passed as arguments to other functions.

The implementation of list<T> has needed new implementations of the strategy using the facilities of Boost Phoenix and also Boost Function. It turns out that a combination of both can be used to meet the needs of list<T>.

The fact that the functions are defined by boost::phoenix::function means that they work with phoenix arguments such as 'arg1'. This is the fact which ensures the flexibility needed for the user to build new functions as needed.

### FC++ legacy

The FC++ List Implementation and the FC++ Reuser Implementation have been followed very closely in building this code. The version used as the starting point was the Boost FC++ version.

### Polymorphic Function Types

Functions are implemented as a struct within namespace impl. For an example funcion 'x' the type is defined like this:

    typedef boost::phoenix::function<impl::X> X;
    X x

This alternative will work to provide a function 'x' but it is not then possible to pass it as an argument.

    BOOST_PHOENIX_ADAPT_CALLABLE(x, impl::X, 1)

#### Implementation Example

This example implements id() which simply returns its argument:

    namespace impl {

      struct Id
      {
        template <typename Sig>
        struct result;

        template <typename This, typename A0>
        struct result<This(A0)>
           : boost::remove_reference<A0>
        {};

        template <typename A0>
        A0 operator()(A0 const & a0) const
        {
            return a0;
        }

      };

    }

    typedef boost::phoenix::function<impl::Id> Id;
    Id id;

### Functions with defined return type

Sometimes it is necessary to define a function using a templated struct, where the template parameter type defines the return type.

#### Example with one argument

    namespace impl {

      template <typename Result>
      struct what {

        typedef Result result_type;

        Result operator()(Result const & r) const
        {
          return r;
        }
      };

    }

    boost::function1<int, int > what_int = impl::what<int>();
    typedef boost::function1<int,int> fun1_int_int;
    typedef boost::phoenix::function<fun1_int_int> What_arg;
    What_arg what_arg(what_int);

#### Example with zero arguments

    namespace impl {
      template <typename Result>
      struct what0 {

        typedef Result result_type;

        Result operator()() const
        {
          return Result(100);
        }

      };
    }

    typedef boost::function0<int> fun0_int;
    boost::function0<int> what0_int = impl::what0<int>();
    typedef boost::phoenix::function<fun0_int> What0_arg;
    What0_arg what0_arg(what0_int);

### List Generation Implementation

The implementation of the function

    enum_from(1)

requires a functor which will evaluate the successive numbers on demand. The code from FC++ has been reimplemented using internal functors as follows.

This code has to carefully manipulate the input type T to construct the result type which is a list.

The code in EFH is used to build a series of objects which each add one element to the list and return the function which will add the next element. That only gets called when it is needed.

          template <class T>
          struct EFH
          {
              mutable T x;
              EFH( const T& xx) : x(xx) {}
              template <typename Sig> struct result;

              template <typename This, class TT>
              struct result<This(TT)>
              {
                typedef typename boost::phoenix::UseList::template
                        List<TT>::type LType;
                typedef typename boost::phoenix::result_of::
                        ListType<LType>::delay_result_type type;
              };
              typename result<EFH(T)>::type operator()() const {
                typedef typename UseList::template List<T>::type LType;
                typedef typename result_of::ListType<LType>::
                        delay_result_type result_type;
                typedef boost::function0<result_type> fun1_R_TTT;
                ++x;
                fun1_R_TTT efh_R_TTT = EFH<T>(x);
                typedef boost::phoenix::function<fun1_R_TTT> EFH_R_T;
                EFH_R_T efh_R_T(efh_R_TTT);
    #ifndef BOOST_PHOENIX_NO_LAZY_EXCEPTIONS
                if (x > BOOST_PHOENIX_FUNCTION_MAX_LAZY_LIST_LENGTH)
                     throw lazy_exception("Running away in EFH!!");
    #endif
                return cons( x-1, efh_R_T() );
              }
          };

          struct Enum_from {
             template <typename Sig> struct result;

             template <typename This, typename T>
             struct result<This(T)>
             {
               typedef typename boost::remove_reference<T>::type TT;
               typedef typename boost::remove_const<TT>::type TTT;
               typedef typename UseList::template List<TTT>::type LType;
               typedef typename result_of::ListType<LType>::
                       delay_result_type type;
             };

             template <class T>
             typename result<Enum_from(T)>::type operator()
                (const T & x) const
              {
                typedef typename boost::remove_reference<T>::type TT;
                typedef typename boost::remove_const<TT>::type TTT;
                typedef typename UseList::template List<T>::type LType;
                typedef typename result_of::ListType<LType>::
                        delay_result_type result_type;
                typedef boost::function0<result_type> fun1_R_TTT;
                fun1_R_TTT efh_R_TTT = EFH<TTT>(x);
                typedef boost::phoenix::function<fun1_R_TTT> EFH_R_T;
                EFH_R_T efh_R_T(efh_R_TTT);
                //std::cout << "enum_from (" << x << ")" << std::endl;
                return efh_R_T();
              }
          };

Similar code is used in the related functors

    enum_from_to
    filter

### Conclusion

These implementation mechanisms have been carried through consistently in the implementation.