<commit_before>/*!
  @file XYZReader.hpp
  @brief definition of a class that reads xyz file.
  
  @author <NAME> (<EMAIL>)
  @date 2017-01-05 17:00
  @copyright <NAME> 2016 on MIT License
*/

#ifndef COFFEE_MILL_XYZ_READER
#define COFFEE_MILL_XYZ_READER
#include <mill/data/XYZData.hpp>
#include <memory>
#include <utility>
#include <iostream>
#include <fstream>
#include <stdexcept>
#include <string>
#include <vector>

namespace mill
{

//! read XYZfile and return the data as std::vector<std::vector<position>>.
/*!
 *  @tparam vectorT type of position
 */
template<typename vectorT>
class XYZReader
{
  public:
    using vector_type     = vectorT;
    using position_type   = vector_type;
    using frame_type      = XYZFrame<position_type>;
    using trajectory_type = std::vector<frame_type>;

  public:

    XYZReader(const std::string& fname): xyz_(fname)
    {
        if(!xyz_.good())
        {
            throw std::runtime_error("XYZReader: file open error: " + fname);
        }
    }
    ~XYZReader() = default;

    trajectory_type read();
    snapshot_type   read_frame();

    bool is_eof() const noexcept {return xyz_.eof();}

  private:
    std::ifstream xyz_;
};

template<typename vecT>
typename XYZReader<vecT>::trajectory_type XYZReader<vecT>::read()
{
    trajectory_type traj;
    while(!this->xyz_.eof())
    {
        traj.push_back(this->read_frame());
    }
    return traj;
}

template<typename vecT>
typename XYZReader<vecT>::frame_type XYZReader<vecT>::read_frame()
{
    std::string line;
    std::getline(this->xyz_, line);
    std::size_t N = 0;
    try
    {
        N = std::stoull(line);
    }
    catch(...)
    {
        throw std::runtime_error("XYZReader::read_frame: expected number, "
                "but get " + line);
    }
    frame_type frame;
    std::getline(this->xyz_, frame.comment);
    frame.particles.reserve(N);<commit_msg>fix: peek before checking eof flag<commit_after>/*!
  @file XYZReader.hpp
  @brief definition of a class that reads xyz file.
  
  @author <NAME> (<EMAIL>)
  @date 2017-01-05 17:00
  @copyright <NAME> 2016 on MIT License
*/

#ifndef COFFEE_MILL_XYZ_READER
#define COFFEE_MILL_XYZ_READER
#include <mill/data/XYZData.hpp>
#include <memory>
#include <utility>
#include <iostream>
#include <fstream>
#include <stdexcept>
#include <string>
#include <vector>

namespace mill
{

//! read XYZfile and return the data as std::vector<std::vector<position>>.
/*!
 *  @tparam vectorT type of position
 */
template<typename vectorT>
class XYZReader
{
  public:
    using vector_type     = vectorT;
    using position_type   = vector_type;
    using frame_type      = XYZFrame<position_type>;
    using snapshot_type   = frame_type;
    using trajectory_type = std::vector<frame_type>;

  public:

    XYZReader(const std::string& fname): xyz_(fname)
    {
        if(!xyz_.good())
        {
            throw std::runtime_error("XYZReader: file open error: " + fname);
        }
    }
    ~XYZReader() = default;

    trajectory_type read();
    snapshot_type   read_frame();

    bool is_eof() const noexcept {return xyz_.eof();}

  private:
    std::ifstream xyz_;
};

template<typename vecT>
typename XYZReader<vecT>::trajectory_type XYZReader<vecT>::read()
{
    trajectory_type traj;
    while(!this->xyz_.eof())
    {
        traj.push_back(this->read_frame());
        this->xyz_.peek();
    }
    return traj;
}

template<typename vecT>
typename XYZReader<vecT>::frame_type XYZReader<vecT>::read_frame()
{
    std::string line;
    std::getline(this->xyz_, line);
    std::size_t N = 0;
    try
    {
        N = std::stoull(line);
    }
    catch(...)
    {
        throw std::runtime_error("XYZReader::read_frame: expected number, "
                "but get " + line);
    }
    frame_type frame;
    std::getline(this->xyz_, frame.comment);
    frame.particles.reserve(N);
{'fraction_non_alphanumeric': 0.13369678089304257, 'fraction_numerical': 0.008826583592938734, 'mean_word_length': 3.2574585635359115, 'pattern_counts': {'":': 0, '<': 47, '<?xml version=': 0, '>': 56, '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': '7213146', 'n_tokens_mistral': 1409, 'n_tokens_neox': 1332, 'n_words': 292}