<commit_before>// Copyright (c) 2012, <NAME> (<EMAIL>).
// Distributed under New BSD License.
// (see accompanying file COPYING)

#ifndef __gtp_codec_detail_header_seen__
#define __gtp_codec_detail_header_seen__

#include <cassert>
#include <map>
#include <string>
#include <istream>
#include <ostream>
#include <memory>
#include <stdexcept>
#include <boost/tokenizer.hpp>

namespace gtp
{

///////////////////////////////////////////////////////////////////////////////
// Creates a map that associates every GTP command with its
// associated gtp::CommandType.
//
inline std::map<std::string, CommandType> mapStringToCommand ()
{
  std::map<std::string, CommandType> result;

  result.insert(std::make_pair("protocol_version", CommandType::protocol_version));
  result.insert(std::make_pair("name", CommandType::name));
  result.insert(std::make_pair("version", CommandType::version));
  result.insert(std::make_pair("known_command", CommandType::known_command));
  result.insert(std::make_pair("list_commands", CommandType::list_commands));
  result.insert(std::make_pair("quit", CommandType::quit));
  result.insert(std::make_pair("boardsize", CommandType::boardsize));
  result.insert(std::make_pair("clear_board", CommandType::clear_board));
  result.insert(std::make_pair("komi", CommandType::komi));
  result.insert(std::make_pair("play", CommandType::play));
  result.insert(std::make_pair("genmove", CommandType::genmove));
  result.insert(std::make_pair("undo", CommandType::undo));
  result.insert(std::make_pair("fixed_handicap", CommandType::fixed_handicap));
  result.insert(std::make_pair("place_free_handicap", CommandType::place_free_handicap));
  result.insert(std::make_pair("set_free_handicap", CommandType::set_free_handicap));
  result.insert(std::make_pair("time_settings", CommandType::time_settings));
  result.insert(std::make_pair("time_left", CommandType::time_left));
  result.insert(std::make_pair("final_score", CommandType::final_score));
  result.insert(std::make_pair("final_status_list", CommandType::final_status_list));

  return result;
}

///////////////////////////////////////////////////////////////////////////////
// Creates a map that associates every gtp::CommandType with its
// associated string.
//
inline std::map<CommandType, std::string> mapCommandToString ()
{
  std::map<CommandType, std::string> result;
  for (auto entry : mapStringToCommand())
  {
    result.insert(std::make_pair(entry.second, entry.first));
  }
  return result;
}

///////////////////////////////////////////////////////////////////////////////
// Dumps a gtp::Vertex to the given output stream
//
inline std::ostream& operator<< (std::ostream& out, const Vertex& v)
{
  char column = v.y;
  char row = 'A' + v.x;
  out << row << column << std::endl;
  return out;
}

///////////////////////////////////////////////////////////////////////////////
// Dumps a gtp::Move to the given output stream
//
inline std::ostream& operator<< (std::ostream& out, const Move& move)
{
  char color = move.color == Color::white ? 'W' : 'B';
  out << color << " " << move.vertex;
  return out;
}

///////////////////////////////////////////////////////////////////////////////
// Parses a gtp::Move from the given input stream
//
inline std::istream& operator>>(std::istream& in, Move& move)
{
  //TODO
  return in;
}

///////////////////////////////////////////////////////////////////////////////
// Parses a gtp::Color from the given input stream
//
inline std::istream& operator>>(std::istream& in, Color& color)
{
  //TODO
  return in;
}

///////////////////////////////////////////////////////////////////////////////
// Parses a std::list<gtp::Vertex> from the given input stream
//
inline std::istream& operator>>(std::istream& in, std::list<Vertex>& list)
{
  //TODO
  return in;
}

///////////////////////////////////////////////////////////////////////////////
// Parses a gtp::Score from the given input stream
//
inline std::istream& operator>>(std::istream& in, Score& score)
{
  //TODO
  return in;
}

///////////////////////////////////////////////////////////////////////////////
// Parses a gtp::StoneStatus from the given input stream
//
inline std::istream& operator>>(std::istream& in, StoneStatus& stoneStatus)
{
  //TODO
  return in;
}

///////////////////////////////////////////////////////////////////////////////
// Dumps a gtp::Score to the given output stream
//
inline std::ostream& operator<< (std::ostream& out, const Score& score)
{
  bool draw = score.advantage == 0;

  if (draw) out << "0" << std::endl;
  else if (score.winner == Color::white) out << "W+" << score.advantage << std::endl;
  else out << "B+" << score.advantage << std::endl;

  return out;
}

///////////////////////////////////////////////////////////////////////////////
// Dumps a gtp::CommandType to the given output stream
//
inline std::ostream& operator<< (std::ostream& out, const CommandType& cmd)
{
  static auto command2stringMap (mapCommandToString());
  auto it = command2stringMap.find (cmd);
  assert (it != command2stringMap.end()); // means the map is incomplete!
  out << it->second;
  return out;
}

///////////////////////////////////////////////////////////////////////////////
// Finds out the matching gtp::CommandType for the given stringified command.
//
inline CommandType string2command (const std::string& command)
                            throw (std::exception)
{
  static auto string2commandMap (mapStringToCommand());
  auto it = string2commandMap.find (command);
  if (it == string2commandMap.end()) throw std::exception();
  return it->second;
}

///////////////////////////////////////////////////////////////////////////////
template<size_t index>
struct ParseAux
{
  template<typename Tuple>
  void operator()(std::istream& args, Tuple& tuple)
  {
    enum aux { TUPLE_INDEX = std::tuple_size<Tuple>::value - index};
    typename std::tuple_element<TUPLE_INDEX, Tuple>::type t;
    args >> t;
    // TODO: control errors

    std::get<TUPLE_INDEX>(tuple) = std::move(t);

    // keep parsing
    ParseAux<index - 1> aux;
    aux(args, tuple);
  }
};

///////////////////////////////////////////////////////////////////////////////
template<>
struct ParseAux<0>
{
  template<typename Tuple>
  void operator()(std::istream& args, Tuple& tuple)
  {
    // do nothing
  }
};

///////////////////////////////////////////////////////////////////////////////
template<typename Command>
WhateverCommand processCmd(std::istream& args)
{
  Command cmd;
  typedef decltype(Command::params) Tuple;
  ParseAux<std::tuple_size<Tuple>::value> parser;<commit_msg>Add parsing stuff<commit_after>// Copyright (c) 2012, <NAME> (<EMAIL>).
// Distributed under New BSD License.
// (see accompanying file COPYING)

#ifndef __gtp_codec_detail_header_seen__
#define __gtp_codec_detail_header_seen__

#include <cassert>
#include <map>
#include <string>
#include <istream>
#include <ostream>
#include <memory>
#include <stdexcept>
#include <boost/algorithm/string.hpp>

namespace gtp
{

///////////////////////////////////////////////////////////////////////////////
// Creates a map that associates every GTP command with its
// associated gtp::CommandType.
//
inline std::map<std::string, CommandType> mapStringToCommand ()
{
  std::map<std::string, CommandType> result;

  result.insert(std::make_pair("protocol_version", CommandType::protocol_version));
  result.insert(std::make_pair("name", CommandType::name));
  result.insert(std::make_pair("version", CommandType::version));
  result.insert(std::make_pair("known_command", CommandType::known_command));
  result.insert(std::make_pair("list_commands", CommandType::list_commands));
  result.insert(std::make_pair("quit", CommandType::quit));
  result.insert(std::make_pair("boardsize", CommandType::boardsize));
  result.insert(std::make_pair("clear_board", CommandType::clear_board));
  result.insert(std::make_pair("komi", CommandType::komi));
  result.insert(std::make_pair("play", CommandType::play));
  result.insert(std::make_pair("genmove", CommandType::genmove));
  result.insert(std::make_pair("undo", CommandType::undo));
  result.insert(std::make_pair("fixed_handicap", CommandType::fixed_handicap));
  result.insert(std::make_pair("place_free_handicap", CommandType::place_free_handicap));
  result.insert(std::make_pair("set_free_handicap", CommandType::set_free_handicap));
  result.insert(std::make_pair("time_settings", CommandType::time_settings));
  result.insert(std::make_pair("time_left", CommandType::time_left));
  result.insert(std::make_pair("final_score", CommandType::final_score));
  result.insert(std::make_pair("final_status_list", CommandType::final_status_list));

  return result;
}

///////////////////////////////////////////////////////////////////////////////
// Creates a map that associates every gtp::CommandType with its
// associated string.
//
inline std::map<CommandType, std::string> mapCommandToString ()
{
  std::map<CommandType, std::string> result;
  for (auto entry : mapStringToCommand())
  {
    result.insert(std::make_pair(entry.second, entry.first));
  }
  return result;
}

///////////////////////////////////////////////////////////////////////////////
// Dumps a gtp::Vertex to the given output stream
//
inline std::ostream& operator<< (std::ostream& out, const Vertex& v)
{
  unsigned column = v.y;
  char row = 'A' + v.x;
  out << row << column << std::endl;
  return out;
}

///////////////////////////////////////////////////////////////////////////////
// Parses a gtp::Vertex from the given input stream
//
inline std::istream& operator>>(std::istream& in, Vertex& vertex)
{
  std::string v;
  in >> v;
  boost::to_upper(v);
  if (v.size() < 2 || v.size() > 3)
  {
    in.setstate(std::ios::failbit);
    return in;
  }

  vertex.x = v.at(0) - 'A';
  vertex.y = atoi(&v.c_str()[1]);

  return in;
}

///////////////////////////////////////////////////////////////////////////////
// Parses a gtp::Color from the given input stream
//
inline std::istream& operator>>(std::istream& in, Color& color)
{
  char colorChar;
  in >> colorChar;
  if (in.fail()) return in;
  color = colorChar == 'W' || colorChar == 'w'? Color::white : Color::black;
  return in;
}

///////////////////////////////////////////////////////////////////////////////
// Dumps a gtp::Move to the given output stream
//
inline std::ostream& operator<< (std::ostream& out, const Move& move)
{
  char color = move.color == Color::white ? 'W' : 'B';
  out << color << " " << move.vertex;
  return out;
}

///////////////////////////////////////////////////////////////////////////////
// Parses a gtp::Move from the given input stream
//
inline std::istream& operator>>(std::istream& in, Move& move)
{
  in >> move.color;
  if (!in.fail()) in >> move.vertex;
  return in;
}


///////////////////////////////////////////////////////////////////////////////
// Parses a std::list<gtp::Vertex> from the given input stream
//
inline std::istream& operator>>(std::istream& in, std::list<Vertex>& list)
{
  Vertex vertex;
  while(in >> vertex) list.push_back(vertex);
  return in;
}

///////////////////////////////////////////////////////////////////////////////
// Parses a gtp::Score from the given input stream
//
inline std::istream& operator>>(std::istream& in, Score& score)
{
  std::string s;
  in >> s;
  if (s == "0")
  {
    score.winner = Color::white;
    score.advantage = 0;
  }
  else
  {
    std::stringstream buffer (s);
    buffer >> score.winner;
    if (!buffer.fail()) buffer >> score.advantage;
  }

  return in;
}

///////////////////////////////////////////////////////////////////////////////
// Parses a gtp::StoneStatus from the given input stream
//
inline std::istream& operator>>(std::istream& in, StoneStatus& stoneStatus)
{
  std::string s;
  in >> s;
  boost::to_upper(s);
  
  if (s == "DEAD") stoneStatus = StoneStatus::dead;
  else if (s == "ALIVE") stoneStatus = StoneStatus::alive;
  else if (s == "SEKI") stoneStatus = StoneStatus::seki;
  else in.setstate(std::ios::failbit);

  return in;
}

///////////////////////////////////////////////////////////////////////////////
// Dumps a gtp::Score to the given output stream
//
inline std::ostream& operator<< (std::ostream& out, const Score& score)
{
  bool draw = score.advantage == 0;

  if (draw) out << "0" << std::endl;
  else if (score.winner == Color::white) out << "W+" << score.advantage << std::endl;
  else out << "B+" << score.advantage << std::endl;

  return out;
}

///////////////////////////////////////////////////////////////////////////////
// Dumps a gtp::CommandType to the given output stream
//
inline std::ostream& operator<< (std::ostream& out, const CommandType& cmd)
{
  static auto command2stringMap (mapCommandToString());
  auto it = command2stringMap.find (cmd);
  assert (it != command2stringMap.end()); // means the map is incomplete!
  out << it->second;
  return out;
}

///////////////////////////////////////////////////////////////////////////////
// Finds out the matching gtp::CommandType for the given stringified command.
//
inline CommandType string2command (const std::string& command)
                            throw (std::exception)
{
  static auto string2commandMap (mapStringToCommand());
  auto it = string2commandMap.find (command);
  if (it == string2commandMap.end()) throw std::exception();
  return it->second;
}

///////////////////////////////////////////////////////////////////////////////
template<size_t index>
struct ParseAux
{
  template<typename Tuple>
  void operator()(std::istream& args, Tuple& tuple)
  {
    enum aux { TUPLE_INDEX = std::tuple_size<Tuple>::value - index};
    typename std::tuple_element<TUPLE_INDEX, Tuple>::type t;
    args >> t;

    if (args.fail()) return;

    std::get<TUPLE_INDEX>(tuple) = std::move(t);

    // keep parsing
    ParseAux<index - 1> aux;
    aux(args, tuple);
  }
};

///////////////////////////////////////////////////////////////////////////////
template<>
struct ParseAux<0>
{
  template<typename Tuple>
  void operator()(std::istream& args, Tuple& tuple)
  {
    // do nothing
  }
};

///////////////////////////////////////////////////////////////////////////////
template<typename Command>
WhateverCommand processCmd(std::istream& args)
{
  Command cmd;
  typedef decltype(Command::params) Tuple;
  ParseAux<std::tuple_size<Tuple>::value> parser;
{'fraction_non_alphanumeric': 0.3036273758964005, 'fraction_numerical': 0.0025064401587412103, 'mean_word_length': 2.19341929746554, 'pattern_counts': {'":': 0, '<': 136, '<?xml version=': 0, '>': 108, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4128321', 'n_tokens_mistral': 4057, 'n_tokens_neox': 3992, 'n_words': 961}