#ifndef RESULTS_HPP
#define RESULTS_HPP

#include <cilk/cilk.h>
#include <cilk/reducer.h>
#include "config.hpp"

static const size_t result_size=max_len/2;

struct Results{
  size_t numbers[result_size];
  Reel sum_fp[result_size];
  Results();
  void reset();
};

class ResultsReducer{
private:
  struct Monoid:cilk::monoid_base<Results>{
    static void reduce(Results* left, Results* Right);
  };

  cilk::reducer<Monoid> imp_;
public:
  ResultsReducer();
  size_t& numbers(size_t i);
  Reel& sum_fp(size_t i);
  void reset();
};

extern ResultsReducer cilk_results;

inline
Results::Results(){
  reset();
}

inline void
Results::reset(){
  for(size_t i=0;i<result_size;++i){
    numbers[i]=0;
    sum_fp[i]=0;
  }
}

inline
ResultsReducer::ResultsReducer(){
  reset();
}
inline void
ResultsReducer::Monoid::reduce(Results* left,Results* right){
  for(size_t i=0;i<result_size;++i){
    left->numbers[i]+=right->numbers[i];
    left->sum_fp[i]+=right->sum_fp[i];
  }
}

inline void
ResultsReducer::reset(){
  imp_.view().reset();
}

inline size_t&
ResultsReducer::numbers(size_t i){
  return imp_.view().numbers[i];
}

inline Reel&
ResultsReducer::sum_fp(size_t i){
  return imp_.view().sum_fp[i];
}
#endif
