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 a snapshot of the develop branch, built from commit 26d7d9b59f.
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