Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

This is the documentation for an old version of Boost. Click here to view this page for the latest version.
PrevUpHomeNext

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.


PrevUpHomeNext