ribi::DrawCanvas::DrawCanvas(const std::string& filename)
  : m_canvas{},
    m_color_system{},
    m_coordinat_system{}
{
  assert(fileio::IsRegularFile(filename));
  std::string s;
  {
    std::ifstream f(filename.c_str());
    f >> s;
  }
  assert(s.size() >= 17);
  assert(s.substr(0,8) == std::string("<canvas>"));
  assert(s.substr(s.size() - 9,9) == std::string("</canvas>"));
  {
    const std::vector<std::string> v { GetRegexMatches(s,QRegExp("(<color_system>.*</color_system>)")) };
    assert(v.size() == 1);
    m_color_system = CanvasColorSystems::ToType(ribi::xml::StripXmlTag(v[0]));
  }

  {
    const std::vector<std::string> v { GetRegexMatches(s,QRegExp("(<coordinat_system>.*</coordinat_system>)")) };
    assert(v.size() == 1);
    m_coordinat_system = CanvasCoordinatSystems::ToType(ribi::xml::StripXmlTag(v[0]));
  }
  int n_cols = -1;
  {
    const std::vector<std::string> v { GetRegexMatches(s,QRegExp("(<n_cols>.*</n_cols>)")) };
    assert(v.size() == 1);
    //assert(CanCast<int>(ribi::xml::StripXmlTag(v[0])));
    n_cols = boost::lexical_cast<int>(ribi::xml::StripXmlTag(v[0]));
  }

  m_canvas.push_back( {} );
  {
    const std::vector<std::string> v { GetRegexMatches(s,QRegExp("(<data>.*</data>)")) };
    assert(v.size() == 1 && "(<data>.*</data>) must be present exactly once");
    const std::pair<std::string,std::vector<std::string>> lines { xml::XmlToVector(v[0]) };
    assert(lines.first == "data");
    const std::vector<std::string>& data { lines.second };
    int i = 0;
    for (const std::string& s: data)
    {
      const double d = boost::lexical_cast<double>(s);

      m_canvas.back().push_back(d);
      ++i;
      if (i == n_cols)
      {
        m_canvas.push_back( {} );
        i = 0;
      }
    }
  }
  assert(m_canvas.back().empty());
  m_canvas.pop_back();
}
const std::vector<std::string> ribi::RegexTesterTr1MainDialog::GetRegexMatches(
  const std::string& s,
  const std::string& r) const
{
  if (!this->GetRegexValid(r)) return std::vector<std::string>();
  return GetRegexMatches(s,std::tr1::regex(r, std::tr1::regex_constants::basic));
}
const std::vector<std::string> ribi::RegexTesterQtMainDialog::GetRegexMatches(
    const std::string& s,
    const std::string& r) const
{
    if (!this->GetRegexValid(r)) return std::vector<std::string>();

    return GetRegexMatches(s,QRegExp(r.c_str()));
}
const boost::shared_ptr<ribi::cmap::CenterNode> ribi::cmap::CenterNodeFactory::FromXml(
  const std::string& s
) const noexcept
{
  if (s.size() < 27)
  {
    return nullptr;
  }
  if (s.substr(0,13) != std::string("<center_node>"))
  {
    return nullptr;
  }
  if (s.substr(s.size() - 14,14) != std::string("</center_node>"))
  {
    return nullptr;
  }

  //m_concept
  boost::shared_ptr<Concept> concept;
  {
    const std::vector<std::string> v = GetRegexMatches(s,QRegExp("(<concept>.*</concept>)"));
    assert(v.size() == 1);
    concept = ConceptFactory().FromXml(v[0]);
  }
  //m_x
  double x = 0.0;
  {
    const std::vector<std::string> v = GetRegexMatches(s,QRegExp("(<x>.*</x>)"));
    assert(v.size() == 1);
    x = boost::lexical_cast<double>(ribi::xml::StripXmlTag(v[0]));
  }
  //m_x
  double y = 0.0;
  {
    const std::vector<std::string> v = GetRegexMatches(s,QRegExp("(<y>.*</y>)"));
    assert(v.size() == 1);
    y = boost::lexical_cast<double>(ribi::xml::StripXmlTag(v[0]));
  }
  assert(concept);
  const boost::shared_ptr<CenterNode> node(new CenterNode(concept,x,y,*this));
  assert(node);
  assert(node->ToXml() == s);
  return node;
}
boost::shared_ptr<ribi::Chess::Square> ribi::Chess::Move::ParseFrom(const std::string& s)
{
  boost::shared_ptr<Chess::Square> square;
  static const boost::xpressive::sregex r { boost::xpressive::sregex::compile("[a-h][1-8]") };
  const std::vector<std::string> v = GetRegexMatches(s,r);
  #ifndef NDEBUG
  if (!(v.size() <= 2)) { TRACE(s); }
  #endif
  assert(v.size() <= 2);
  if (v.size() == 2)
  {
    square = SquareFactory().Create(v[0]);
  }
  return square;
}
boost::shared_ptr<ribi::Chess::Square> ribi::Chess::Move::ParseTo(const std::string& s)
{
  static const boost::xpressive::sregex r {
    boost::xpressive::sregex::compile("[a-h][1-8]")
  };

  boost::shared_ptr<Chess::Square> square;
  const std::vector<std::string> v = GetRegexMatches(s,r);
  if (!v.empty())
  {
    assert(v.size() <= 2);
    const std::string t = v[ v.size() - 1];
    square = SquareFactory().Create(t);
    assert(square);
  }
  return square;
}
const boost::shared_ptr<ribi::cmap::Examples> ribi::cmap::ExamplesFactory::FromXml(const std::string& s) const
{
  if (s.size() < 20)
  {
    return nullptr;
  }
  if (s.substr(0,10) != std::string("<examples>"))
  {
    return nullptr;
  }
  if (s.substr(s.size() - 11,11) != std::string("</examples>"))
  {
    return nullptr;
  }

  std::vector<boost::shared_ptr<Example> > examples;
  //m_questions
  {
    const std::vector<std::string> v = GetRegexMatches(s,QRegExp("(<example>.*</example>)"));
    std::transform(v.begin(),v.end(),std::back_inserter(examples),
      [](const std::string& s)
      {
        return ExampleFactory().FromXml(s);
      }
    );
  }
  const boost::shared_ptr<Examples> result {
    Create(examples)
  };
  assert(result);
  #ifndef NDEBUG
  if(result->ToXml() != s)
  {
    TRACE("ERROR");
    TRACE(result->ToXml());
    TRACE(s);
    TRACE("BREAK");
  }

  #endif
  assert(result->ToXml() == s);
  return result;
}