コード記法

id:mb2sync氏の:p-stadeライブラリを使ってstd::accumulateをpipableにしてみる
見様見真似なので正しいかどうかはわからない

#ifndef NUMERIC_DWA20071016_HPP

#if (_MSC_VER >= 1020)
# pragma once
#endif

# define NUMERIC_DWA20071016_HPP

#include <numeric>
#include <boost/range/value_type.hpp>

#include <pstade/adl_barrier.hpp>
#include <pstade/egg/auxiliary.hpp>
#include <pstade/egg/function.hpp>
#include <pstade/pod_constant.hpp>
#include <pstade/egg/pipable.hpp>

#include <boost/static_assert.hpp>
#include <boost/type_traits/is_convertible.hpp>


// 独自名前空間でpipable objectの定義を行う
namespace nlptr {

namespace accumulate_detail
{
  
  struct baby
  {
      // 戻り値とテンプレートパラメータ(関数オブジェクトの指定は任意なのでdefault値void)
      template< class Myself, class Range, class Value, class Function = void>
      struct apply :
        boost::range_value<Range>
      { };
      
      // 関数本体
      template< class Result, class Range, class Value, class Function >
      Result call(Range& rng, Value const& init, Function const& func) const
      {
          // range_value<Range> == Value
          BOOST_STATIC_ASSERT((
                                  boost::is_convertible<
                                  typename boost::range_value<Range>::type, Value
                                  >::value
          ));
          
          return std::accumulate(boost::begin(rng), boost::end(rng), init, func);
      }
      
      // デフォルトの関数オブジェクト
      template< class Result, class Range, class Value>
      Result call(Range& rng, Value const& init) const
      {
          // range_value<Range> == Value
          BOOST_STATIC_ASSERT((
                                  boost::is_convertible<
                                  typename boost::range_value<Range>::type, Value
                                  >::value
          ));
          
          return std::accumulate(boost::begin(rng), boost::end(rng), init);
      }
  };
  
  typedef pstade::egg::function<baby> op;
  
} // namespace accumulate_detail


// std::accumulateと名前が被る?
PSTADE_ADL_BARRIER(nlptr_accumulate) {
    namespace egg = pstade::egg;
    
    PSTADE_POD_CONSTANT(
        (egg::result_of_pipable< accumulate_detail::op >::type)
      , accumulate
    ) = PSTADE_EGG_PIPABLE_L {{}} PSTADE_EGG_PIPABLE_R;
} // adl barrier


} // namespace nlptr


# endif
// NUMERIC_DWA20071016_HPP

使用例

#include <nlptr/algos/numeric.hpp>

#include <iostream>
#include <pstade/oven/counting.hpp>

#include <boost/lambda/lambda.hpp>

int main(void) {
    namespace oven = pstade::oven;
    using boost::lambda::_1;
    using boost::lambda::_2;
    
    assert(
        ( (oven::counting(0,10)|nlptr::accumulate(0)) == 45 ) &&
        ( (oven::counting(0,10)|nlptr::accumulate(0, _1 + _2)) == 45 )
    );
}

いい加減にboost.testの使い方も覚えなければならない