<commit_before>#include <algorithm>
#include <cassert>
#include <iostream>

#include "Builder.hpp"

namespace cda_tries {

Builder::Builder(const std::vector<std::string> &strs, const CodeTable &table)
  : strs_(strs), table_(table) {}

Builder::~Builder() {}

void Builder::build_(bc_type type) {
  if (BC_UPPER < strs_.size()) {
    std::cerr << "Critical error: dic size is too large" << std::endl;
    exit(1);
  }

  if (!bc_.empty()) {
    return;
  }

  switch (type) {
    case bc_type::PLAIN:
      block_size_ = 0;
      break;
    case bc_type::DAC:
      block_size_ = 256;
      break;
    case bc_type::FDAC:
      block_size_ = 128;
      break;
  }
  emp_head_ = NOT_FOUND;

  size_t init_capa = 1;
  while (init_capa < strs_.size()) {
    init_capa <<= 1;
  }

  bc_.reserve(init_capa);
  term_flags_.reserve(init_capa);

  edges_.reserve(256);
  suffixes_.reserve(strs_.size());
  if (block_size_) {
    emp_heads_.reserve(init_capa / block_size_);
  }

  expand_();
  fix_(0);
  arrange_(0, strs_.size(), 0, 0);
  unify_tail_();
}

void Builder::expand_() {
  if (BC_UPPER < bc_.size() + 256) {
    std::cerr << "Critical error: dic size is too large" << std::endl;
    exit(1);
  }

  auto old_size = static_cast<uint32_t>(bc_.size());
  auto new_size = old_size + 256;

  for (uint32_t i = 0; i < 256; ++i) {
    bc_.push_back(bc_t{});
    term_flags_.push_back(false);
  }

  for (auto pos = old_size; pos < new_size; ++pos) {
    set_prev_(pos, pos - 1);
    set_next_(pos, pos + 1);
  }

  if (emp_head_ == NOT_FOUND) {
    set_prev_(old_size, new_size - 1);
    set_next_(new_size - 1, old_size);
    emp_head_ = old_size;
  } else {
    auto emp_tail = prev_(emp_head_);
    set_prev_(old_size, emp_tail);
    set_next_(emp_tail, old_size);
    set_prev_(emp_head_, new_size - 1);
    set_next_(new_size - 1, emp_head_);
  }

  if (block_size_) {
    for (auto pos = old_size; pos < new_size; pos += block_size_) {
      emp_heads_.push_back(pos);
    }
  }

  auto old_block_size = old_size / 256;
  if (FREE_BLOCKS <= old_block_size) {
    fix_block_(old_block_size - FREE_BLOCKS);
  }
}

void Builder::fix_(uint32_t pos) {
  assert(!bc_[pos].is_fixed());
  bc_[pos].fix();

  auto prev = prev_(pos);
  auto next = next_(pos);
  set_prev_(next, prev);
  set_next_(prev, next);

  if (pos == emp_head_) {
    emp_head_ = pos == next ? NOT_FOUND : next;
  }

  if (block_size_) {
    auto block_pos = pos / block_size_;
    if (pos != emp_heads_[block_pos]) {
      return;
    }
    if (emp_head_ == NOT_FOUND || block_pos != next / block_size_) {
      emp_heads_[block_pos] = NOT_FOUND;
    } else {
      emp_heads_[block_pos] = next;
    }
  }
}

void Builder::fix_block_(uint32_t block_pos) {
  auto begin = block_pos * 256;
  auto end = begin + 256;

  for (auto pos = begin; pos < end; ++pos) {
    if (!bc_[pos].is_fixed()) {
      fix_(pos);
      bc_[pos].unfix();
    }
  }

  if (block_size_) {
    for (auto pos = begin; pos < end; pos += block_size_) {
      emp_heads_[pos / block_size_] = NOT_FOUND;
    }
  }
}

void Builder::arrange_(size_t begin, size_t end, size_t depth, uint32_t node_pos) {
  if (strs_[begin].size() == depth) {
    ++begin;
    term_flags_[node_pos] = true;
    if (begin == end) { // without link
      bc_[node_pos].set_link(0);
      return;
    }
  }

  if (begin + 1 == end && !term_flags_[node_pos]) { // is leaf
    if (strs_[begin].size() == depth) {
      std::cerr << "Critical error: dic includes overlapped strs" << std::endl;
      exit(1);
    }
    term_flags_[node_pos] = true;
    auto &str = strs_[begin];
    suffix_t suffix(str.c_str() + depth, str.size() - depth, node_pos);
    suffixes_.push_back(suffix);
    return;
  }

  { // fetch edges
    edges_.clear();
    auto label = static_cast<uint8_t>(strs_[begin][depth]);
    for (auto str_id = begin + 1; str_id < end; ++str_id) {
      auto _label = static_cast<uint8_t>(strs_[str_id][depth]);
      if (label != _label) {
        if (_label < label) {
          std::cerr << "Critical error: dic is unsorted" << std::endl;
          exit(1);
        }
        edges_.push_back(label);
        label = _label;
      }
    }
    edges_.push_back(label);
  }

#ifdef ENABLE_YCHECK
  auto base = block_size_ ? ycheck_(node_pos / block_size_) : xcheck_();
#else
  auto base = xcheck_();
#endif

  if (bc_.size() <= base) {
    expand_();
  }

  // define
  bc_[node_pos].set_base(base);
  for (auto label : edges_) {
    auto child_pos = base ^ table_.code(label);
    fix_(child_pos);
    bc_[child_pos].set_check(node_pos);
  }

  // follow
  auto _begin = begin;
  auto label = static_cast<uint8_t>(strs_[begin][depth]);
  for (auto _end = begin + 1; _end < end; ++_end) {
    auto _label = static_cast<uint8_t>(strs_[_end][depth]);
    if (label != _label) {
      arrange_(_begin, _end, depth + 1, base ^ table_.code(label));
      label = _label;
      _begin = _end;
    }
  }
  arrange_(_begin, end, depth + 1, base ^ table_.code(label));
}

uint32_t Builder::xcheck_() const {
  if (emp_head_ == NOT_FOUND) {
    return static_cast<uint32_t>(bc_.size()) ^ edges_[0];
  }

  auto pos = emp_head_;
  do {
    auto base = pos ^ table_.code(edges_[0]);
    if (is_target_(base)) {
      return base;
    }
    pos = next_(pos);
  } while (emp_head_ != pos);

  return static_cast<uint32_t>(bc_.size()) ^ edges_[0];
}

uint32_t Builder::ycheck_(uint32_t block_pos) const {
  if (emp_head_ == NOT_FOUND) {
    return static_cast<uint32_t>(bc_.size()) ^ edges_[0];
  }

  auto pos = emp_heads_[block_pos];
  if (pos != NOT_FOUND) {
    do {
      auto base = pos ^ table_.code(edges_[0]);
      if (is_target_(base)) {
        return base;
      }
      pos = next_(pos);
      if (pos / block_size_ != block_pos) {
        break;
      }
    } while (emp_head_ != pos);
  }

  return xcheck_();
}

bool Builder::is_target_(uint32_t base) const {
  for (auto label : edges_) {
    auto pos = base ^ table_.code(label);
    if (bc_[pos].is_fixed()) {
      return false;
    }
  }
  return true;
}

void Builder::unify_tail_() {
  auto comp_suffix = [](const suffix_t &lhs, const suffix_t &rhs) {
    for (size_t i = 0; i < lhs.size(); ++i) {
      if (i == rhs.size()) {
        return false;
      }
      if (lhs[i] != rhs[i]) {
        return static_cast<uint8_t>(lhs[i]) < static_cast<uint8_t>(rhs[i]);
      }
    }
    return lhs.size() < rhs.size();
  };

  auto can_unify = [](const suffix_t &lhs, const suffix_t &rhs) {
    if (lhs.size() > rhs.size()) {
      return false;
    }
    for (size_t i = 0; i < lhs.size(); ++i) {
      if (lhs[i] != rhs[i]) {
        return false;
      }
    }
    return true;
  };

  std::sort(suffixes_.begin(), suffixes_.end(), comp_suffix);
  tail_.push_back('\0');

  size_t begin = 0;
  for (size_t i = 1; i < suffixes_.size(); ++i) {
    auto &lhs = suffixes_[i - 1];
    auto &rhs = suffixes_[i];

    if (can_unify(lhs, rhs)) {
      continue;
    }

    append_tail_(begin, i, lhs.str());
    begin = i;
  }

  append_tail_(begin, suffixes_.size(), suffixes_.back().str());
}

void Builder::append_tail_(size_t begin, size_t end, const char *str) {
  while (*str != '\0') {
    tail_.push_back(*str++);
  }
  while (begin < end) {
    auto &suffix = suffixes_[begin++];
    auto tail_pos = static_cast<uint32_t>(tail_.size() - suffix.size());
    assert(tail_pos <= BC_UPPER);
    bc_[suffix.node_pos()].set_link(tail_pos);
  }
  tail_.push_back('\0');
}

} // cda_tries
<commit_msg>minor revision<commit_after>#include <algorithm>
#include <cassert>
#include <iostream>

#include "Builder.hpp"

namespace cda_tries {

Builder::Builder(const std::vector<std::string> &strs, const CodeTable &table)
  : strs_(strs), table_(table) {}

Builder::~Builder() {}

void Builder::build_(bc_type type) {
  if (BC_UPPER < strs_.size()) {
    std::cerr << "Critical error: dic size is too large" << std::endl;
    exit(1);
  }

  if (!bc_.empty()) {
    return;
  }

  switch (type) {
    case bc_type::PLAIN:
      block_size_ = 0;
      break;
    case bc_type::DAC:
      block_size_ = 256;
      break;
    case bc_type::FDAC:
      block_size_ = 128;
      break;
  }
  emp_head_ = NOT_FOUND;

  size_t init_capa = 1;
  while (init_capa < strs_.size()) {
    init_capa <<= 1;
  }

  bc_.reserve(init_capa);
  term_flags_.reserve(init_capa);

  edges_.reserve(256);
  suffixes_.reserve(strs_.size());
  if (block_size_) {
    emp_heads_.reserve(init_capa / block_size_);
  }

  expand_();
  fix_(0);
  arrange_(0, strs_.size(), 0, 0);
  unify_tail_();
}

void Builder::expand_() {
  if (BC_UPPER < bc_.size() + 256) {
    std::cerr << "Critical error: dic size is too large" << std::endl;
    exit(1);
  }

  auto old_size = static_cast<uint32_t>(bc_.size());
  auto new_size = old_size + 256;

  for (uint32_t i = 0; i < 256; ++i) {
    bc_.push_back(bc_t{});
    term_flags_.push_back(false);
  }

  for (auto pos = old_size; pos < new_size; ++pos) {
    set_prev_(pos, pos - 1);
    set_next_(pos, pos + 1);
  }

  if (emp_head_ == NOT_FOUND) {
    set_prev_(old_size, new_size - 1);
    set_next_(new_size - 1, old_size);
    emp_head_ = old_size;
  } else {
    auto emp_tail = prev_(emp_head_);
    set_prev_(old_size, emp_tail);
    set_next_(emp_tail, old_size);
    set_prev_(emp_head_, new_size - 1);
    set_next_(new_size - 1, emp_head_);
  }

  if (block_size_) {
    for (auto pos = old_size; pos < new_size; pos += block_size_) {
      emp_heads_.push_back(pos);
    }
  }

  auto old_block_size = old_size / 256;
  if (FREE_BLOCKS <= old_block_size) {
    fix_block_(old_block_size - FREE_BLOCKS);
  }
}

void Builder::fix_(uint32_t pos) {
  assert(!bc_[pos].is_fixed());
  bc_[pos].fix();

  auto prev = prev_(pos);
  auto next = next_(pos);
  set_prev_(next, prev);
  set_next_(prev, next);

  if (pos == emp_head_) {
    emp_head_ = pos == next ? NOT_FOUND : next;
  }

  if (block_size_) {
    auto block_pos = pos / block_size_;
    if (pos != emp_heads_[block_pos]) {
      return;
    }
    if (emp_head_ == NOT_FOUND || block_pos != next / block_size_) {
      emp_heads_[block_pos] = NOT_FOUND;
    } else {
      emp_heads_[block_pos] = next;
    }
  }
}

void Builder::fix_block_(uint32_t block_pos) {
  auto begin = block_pos * 256;
  auto end = begin + 256;

  for (auto pos = begin; pos < end; ++pos) {
    if (!bc_[pos].is_fixed()) {
      fix_(pos);
      bc_[pos].unfix();
    }
  }

  if (block_size_) {
    for (auto pos = begin; pos < end; pos += block_size_) {
      emp_heads_[pos / block_size_] = NOT_FOUND;
    }
  }
}

void Builder::arrange_(size_t begin, size_t end, size_t depth, uint32_t node_pos) {
  if (strs_[begin].size() == depth) {
    ++begin;
    term_flags_[node_pos] = true;
    if (begin == end) { // without link
      bc_[node_pos].set_link(0);
      return;
    }
  }

  if (begin + 1 == end && !term_flags_[node_pos]) { // is leaf
    if (strs_[begin].size() == depth) {
      std::cerr << "Critical error: dic includes overlapped strs" << std::endl;
      exit(1);
    }
    term_flags_[node_pos] = true;
    auto &str = strs_[begin];
    suffix_t suffix(str.c_str() + depth, str.size() - depth, node_pos);
    suffixes_.push_back(suffix);
    return;
  }

  { // fetch edges
    edges_.clear();
    auto label = static_cast<uint8_t>(strs_[begin][depth]);
    for (auto str_id = begin + 1; str_id < end; ++str_id) {
      auto _label = static_cast<uint8_t>(strs_[str_id][depth]);
      if (label != _label) {
        if (_label < label) {
          std::cerr << "Critical error: dic is unsorted" << std::endl;
          exit(1);
        }
        edges_.push_back(label);
        label = _label;
      }
    }
    edges_.push_back(label);
  }

#ifdef ENABLE_YCHECK
  auto base = block_size_ ? ycheck_(node_pos / block_size_) : xcheck_();
#else
  auto base = xcheck_();
#endif

  if (bc_.size() <= base) {
    expand_();
  }

  // define
  bc_[node_pos].set_base(base);
  for (auto label : edges_) {
    auto child_pos = base ^ table_.code(label);
    fix_(child_pos);
    bc_[child_pos].set_check(node_pos);
  }

  // follow
  auto _begin = begin;
  auto label = static_cast<uint8_t>(strs_[begin][depth]);
  for (auto _end = begin + 1; _end < end; ++_end) {
    auto _label = static_cast<uint8_t>(strs_[_end][depth]);
    if (label != _label) {
      arrange_(_begin, _end, depth + 1, base ^ table_.code(label));
      label = _label;
      _begin = _end;
    }
  }
  arrange_(_begin, end, depth + 1, base ^ table_.code(label));
}

uint32_t Builder::xcheck_() const {
  if (emp_head_ == NOT_FOUND) {
    return static_cast<uint32_t>(bc_.size()) ^ table_.code(edges_[0]);
  }

  auto pos = emp_head_;
  do {
    auto base = pos ^ table_.code(edges_[0]);
    if (is_target_(base)) {
      return base;
    }
    pos = next_(pos);
  } while (emp_head_ != pos);

  return static_cast<uint32_t>(bc_.size()) ^ table_.code(edges_[0]);
}

uint32_t Builder::ycheck_(uint32_t block_pos) const {
  if (emp_head_ == NOT_FOUND) {
    return static_cast<uint32_t>(bc_.size()) ^ table_.code(edges_[0]);
  }

  auto pos = emp_heads_[block_pos];
  if (pos != NOT_FOUND) {
    do {
      auto base = pos ^ table_.code(edges_[0]);
      if (is_target_(base)) {
        return base;
      }
      pos = next_(pos);
      if (pos / block_size_ != block_pos) {
        break;
      }
    } while (emp_head_ != pos);
  }

  return xcheck_();
}

bool Builder::is_target_(uint32_t base) const {
  for (auto label : edges_) {
    auto pos = base ^ table_.code(label);
    if (bc_[pos].is_fixed()) {
      return false;
    }
  }
  return true;
}

void Builder::unify_tail_() {
  auto comp_suffix = [](const suffix_t &lhs, const suffix_t &rhs) {
    for (size_t i = 0; i < lhs.size(); ++i) {
      if (i == rhs.size()) {
        return false;
      }
      if (lhs[i] != rhs[i]) {
        return static_cast<uint8_t>(lhs[i]) < static_cast<uint8_t>(rhs[i]);
      }
    }
    return lhs.size() < rhs.size();
  };

  auto can_unify = [](const suffix_t &lhs, const suffix_t &rhs) {
    if (lhs.size() > rhs.size()) {
      return false;
    }
    for (size_t i = 0; i < lhs.size(); ++i) {
      if (lhs[i] != rhs[i]) {
        return false;
      }
    }
    return true;
  };

  std::sort(suffixes_.begin(), suffixes_.end(), comp_suffix);
  tail_.push_back('\0');

  size_t begin = 0;
  for (size_t i = 1; i < suffixes_.size(); ++i) {
    auto &lhs = suffixes_[i - 1];
    auto &rhs = suffixes_[i];

    if (can_unify(lhs, rhs)) {
      continue;
    }

    append_tail_(begin, i, lhs.str());
    begin = i;
  }

  append_tail_(begin, suffixes_.size(), suffixes_.back().str());
}

void Builder::append_tail_(size_t begin, size_t end, const char *str) {
  while (*str != '\0') {
    tail_.push_back(*str++);
  }
  while (begin < end) {
    auto &suffix = suffixes_[begin++];
    auto tail_pos = static_cast<uint32_t>(tail_.size() - suffix.size());
    assert(tail_pos <= BC_UPPER);
    bc_[suffix.node_pos()].set_link(tail_pos);
  }
  tail_.push_back('\0');
}

} // cda_tries
<|endoftext|>


<commit_before>/***********************************************************************
 datetime.cpp - Implements date and time classes compatible with MySQL's
	various date and time column types.

 Copyright (c) 1998 by Kevin Atkinson, (c) 1999-2001 by MySQL AB, and
 (c) 2004-2007 by Educational Technology Resources, Inc.  Others may
 also hold copyrights on code in this file.  See the CREDITS file in
 the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#define MYSQLPP_NOT_HEADER
#include "common.h"

#include "datetime.h"
#include "stream2string.h"

#include <iomanip>

#include <time.h>

using namespace std;

namespace mysqlpp {

template <class T>
DTbase<T>::operator std::string() const
{
	return stream2string(*this);
}

std::ostream& operator <<(std::ostream& os, const Date& d)
{
	char fill = os.fill('0');
	ios::fmtflags flags = os.setf(ios::right);
	os		<< setw(4) << d.year << '-'
			<< setw(2) << d.month << '-'
			<< setw(2) << d.day;
	os.flags(flags);
	os.fill(fill);
	return os;
}

std::ostream& operator <<(std::ostream& os, const Time& t)
{
	char fill = os.fill('0');
	ios::fmtflags flags = os.setf(ios::right);
	os		<< setw(2) << t.hour << ':'
			<< setw(2) << t.minute << ':'
			<< setw(2) << t.second;
	os.flags(flags);
	os.fill(fill);
	return os;
}

std::ostream& operator <<(std::ostream& os, const DateTime& dt)
{
	operator <<(os, Date(dt));
	os << ' ';
	return operator <<(os, Time(dt));
}

cchar* Date::convert(cchar* str)
{
	char num[5];

	num[0] = *str++;
	num[1] = *str++;
	num[2] = *str++;
	num[3] = *str++;
	num[4] = 0;
	year = static_cast<unsigned short>(strtol(num, 0, 10));
	if (*str == '-') str++;

	num[0] = *str++;
	num[1] = *str++;
	num[2] = 0;
	month = static_cast<unsigned char>(strtol(num, 0, 10));
	if (*str == '-') str++;

	num[0] = *str++;
	num[1] = *str++;
	num[2] = 0;
	day = static_cast<unsigned char>(strtol(num, 0, 10));

	return str;
}

cchar* Time::convert(cchar* str)
{
	char num[5];

	num[0] = *str++;
	num[1] = *str++;
	num[2] = 0;
	hour = static_cast<unsigned char>(strtol(num,0,10));
	if (*str == ':') str++;

	num[0] = *str++;
	num[1] = *str++;
	num[2] = 0;
	minute = static_cast<unsigned char>(strtol(num,0,10));
	if (*str == ':') str++;

	num[0] = *str++;
	num[1] = *str++;
	num[2] = 0;
	second = static_cast<unsigned char>(strtol(num,0,10));

	return str;
}

cchar* DateTime::convert(cchar* str)
{
	Date d;
	str = d.convert(str);
	year = d.year;
	month = d.month;
	day = d.day;

	if (*str == ' ') ++str;

	Time t;
	str = t.convert(str);
	hour = t.hour;
	minute = t.minute;
	second = t.second;

	return str;
}

int Date::compare(const Date& other) const
{
	if (year != other.year) return year - other.year;
	if (month != other.month) return month - other.month;
	return day - other.day;
}

int Time::compare(const Time& other) const
{
	if (hour != other.hour) return hour - other.hour;
	if (minute != other.minute) return minute - other.minute;
	return second - other.second;
}

int DateTime::compare(const DateTime& other) const
{
	Date d(*this), od(other);
	Time t(*this), ot(other);

	if (int x = d.compare(od)) {
		return x;
	}
	else {
		return t.compare(ot);
	}
}

DateTime::operator time_t() const
{
	struct tm tm;
	tm.tm_sec = second;
	tm.tm_min = minute;
	tm.tm_hour = hour;
	tm.tm_mday = day;
	tm.tm_mon = month - 1;
	tm.tm_year = year - 1900;
	tm.tm_isdst = -1;

	return mktime(&tm);
};

DateTime::DateTime(time_t t)
{
	struct tm tm;
#if defined(_MSC_VER) && _MSC_VER >= 1400 && !defined(_STLP_VERSION) && \
		!defined(_STLP_VERSION_STR)
	// Use thread-safe localtime() replacement included with VS2005 and
	// up, but only when using native RTL, not STLport.
	localtime_s(&tm, &t);
#elif defined(HAVE_LOCALTIME_R)
	// Detected POSIX thread-safe localtime() replacement.
	localtime_r(&t, &tm);
#else
	// No explicitly thread-safe localtime() replacement found.  This
	// may still be thread-safe, as some C libraries take special steps
	// within localtime() to get thread safety.  For example, thread-
	// local storage (TLS) in some Windows compilers.
	memcpy(&tm, localtime(&t), sizeof(tm));
#endif

	year = tm.tm_year + 1900;
	month = tm.tm_mon + 1;
	day = tm.tm_mday;
	hour = tm.tm_hour;
	minute = tm.tm_min;
	second = tm.tm_sec;
}

} // end namespace mysqlpp

<commit_msg>Previous checkin broke Date/Time operator<<()'s.  Fixed.<commit_after>/***********************************************************************
 datetime.cpp - Implements date and time classes compatible with MySQL's
	various date and time column types.

 Copyright (c) 1998 by Kevin Atkinson, (c) 1999-2001 by MySQL AB, and
 (c) 2004-2007 by Educational Technology Resources, Inc.  Others may
 also hold copyrights on code in this file.  See the CREDITS file in
 the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#define MYSQLPP_NOT_HEADER
#include "common.h"

#include "datetime.h"
#include "stream2string.h"

#include <iomanip>

#include <time.h>

using namespace std;

namespace mysqlpp {

template <class T>
DTbase<T>::operator std::string() const
{
	return stream2string(*this);
}

std::ostream& operator <<(std::ostream& os, const Date& d)
{
	char fill = os.fill('0');
	ios::fmtflags flags = os.setf(ios::right);
	os		<< setw(4) << d.year << '-'
			<< setw(2) << static_cast<int>(d.month) << '-'
			<< setw(2) << static_cast<int>(d.day);
	os.flags(flags);
	os.fill(fill);
	return os;
}

std::ostream& operator <<(std::ostream& os, const Time& t)
{
	char fill = os.fill('0');
	ios::fmtflags flags = os.setf(ios::right);
	os		<< setw(2) << static_cast<int>(t.hour) << ':'
			<< setw(2) << static_cast<int>(t.minute) << ':'
			<< setw(2) << static_cast<int>(t.second);
	os.flags(flags);
	os.fill(fill);
	return os;
}

std::ostream& operator <<(std::ostream& os, const DateTime& dt)
{
	operator <<(os, Date(dt));
	os << ' ';
	return operator <<(os, Time(dt));
}

cchar* Date::convert(cchar* str)
{
	char num[5];

	num[0] = *str++;
	num[1] = *str++;
	num[2] = *str++;
	num[3] = *str++;
	num[4] = 0;
	year = static_cast<unsigned short>(strtol(num, 0, 10));
	if (*str == '-') str++;

	num[0] = *str++;
	num[1] = *str++;
	num[2] = 0;
	month = static_cast<unsigned char>(strtol(num, 0, 10));
	if (*str == '-') str++;

	num[0] = *str++;
	num[1] = *str++;
	num[2] = 0;
	day = static_cast<unsigned char>(strtol(num, 0, 10));

	return str;
}

cchar* Time::convert(cchar* str)
{
	char num[5];

	num[0] = *str++;
	num[1] = *str++;
	num[2] = 0;
	hour = static_cast<unsigned char>(strtol(num,0,10));
	if (*str == ':') str++;

	num[0] = *str++;
	num[1] = *str++;
	num[2] = 0;
	minute = static_cast<unsigned char>(strtol(num,0,10));
	if (*str == ':') str++;

	num[0] = *str++;
	num[1] = *str++;
	num[2] = 0;
	second = static_cast<unsigned char>(strtol(num,0,10));

	return str;
}

cchar* DateTime::convert(cchar* str)
{
	Date d;
	str = d.convert(str);
	year = d.year;
	month = d.month;
	day = d.day;

	if (*str == ' ') ++str;

	Time t;
	str = t.convert(str);
	hour = t.hour;
	minute = t.minute;
	second = t.second;

	return str;
}

int Date::compare(const Date& other) const
{
	if (year != other.year) return year - other.year;
	if (month != other.month) return month - other.month;
	return day - other.day;
}

int Time::compare(const Time& other) const
{
	if (hour != other.hour) return hour - other.hour;
	if (minute != other.minute) return minute - other.minute;
	return second - other.second;
}

int DateTime::compare(const DateTime& other) const
{
	Date d(*this), od(other);
	Time t(*this), ot(other);

	if (int x = d.compare(od)) {
		return x;
	}
	else {
		return t.compare(ot);
	}
}

DateTime::operator time_t() const
{
	struct tm tm;
	tm.tm_sec = second;
	tm.tm_min = minute;
	tm.tm_hour = hour;
	tm.tm_mday = day;
	tm.tm_mon = month - 1;
	tm.tm_year = year - 1900;
	tm.tm_isdst = -1;

	return mktime(&tm);
};

DateTime::DateTime(time_t t)
{
	struct tm tm;
#if defined(_MSC_VER) && _MSC_VER >= 1400 && !defined(_STLP_VERSION) && \
		!defined(_STLP_VERSION_STR)
	// Use thread-safe localtime() replacement included with VS2005 and
	// up, but only when using native RTL, not STLport.
	localtime_s(&tm, &t);
#elif defined(HAVE_LOCALTIME_R)
	// Detected POSIX thread-safe localtime() replacement.
	localtime_r(&t, &tm);
#else
	// No explicitly thread-safe localtime() replacement found.  This
	// may still be thread-safe, as some C libraries take special steps
	// within localtime() to get thread safety.  For example, thread-
	// local storage (TLS) in some Windows compilers.
	memcpy(&tm, localtime(&t), sizeof(tm));
#endif

	year = tm.tm_year + 1900;
	month = tm.tm_mon + 1;
	day = tm.tm_mday;
	hour = tm.tm_hour;
	minute = tm.tm_min;
	second = tm.tm_sec;
}

} // end namespace mysqlpp

<|endoftext|>


<commit_before>#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <sys/wait.h>

#define MAX_LINE 80
#define MAX_ARGS 4
#define MAX_HISTORY 10

char history[MAX_HISTORY][MAX_LINE] ;
char stackCounter;

void pushToHistory (char string[]) {
	if (stackCounter >= MAX_HISTORY) {
		//Move the stack
		for(char i = 1; i < MAX_HISTORY; i++) {
			strcpy(history[i - 1], history[i]);
		}
		stackCounter = MAX_HISTORY - 1;
	}
	strcpy(history[stackCounter], string);
	stackCounter++;
}

void printPointerArray(char *args[], char len) {
	printf("printArray > ARRAY LEN: %d\n", len);
	for (char i = 0; i < len; i++) {
		printf("[%d] %s\n", i, args[i]);
	}
}

void showHistory(int signum) {
    if (signum == SIGINT) {
        char message[] = "\n\nCurrent history: \n\n";
        write(STDOUT_FILENO, message, strlen(message));
        for (char i = 0; i < MAX_HISTORY; i++) {
            if (strlen(history[i])) {
                char command[85];
                sprintf(command, "%d %s\n",i + 1, history[i]);
                write(STDOUT_FILENO, command, strlen(command));
            } else {
                break;
            }
        }
    }
}

int findCommand(char initWith[]) {
    for (char i = 0; i < MAX_HISTORY; i++) {
        if (strlen(history[i])) {
            if(strncmp(history[i], initWith, strlen(initWith)) == 0) {
                return i;
            }
        } else {
            break;
        }
    }
    return -1;
}
void emptyPointerArray(char *args[], char len) {
	for (char i = 0; i < len; i++) {
		free(args[i]);
		args[i] = NULL;
	}
}

void splitStringBySpace(char *args[], char inputBuffer[], int *elements) {
	char currentIndex = -1;
	char size = 0;
	char lenght = strlen(inputBuffer);
	for (char i = 0 ; i < lenght ; i++) {
		if (inputBuffer[i] == ' ') {
			if (size > 0) {
				args[++currentIndex] = (char *) malloc ((size + 1) * sizeof(char));
				for (char j = 0; j < size; j++) {
					*(args[currentIndex] + j) = inputBuffer[i - size + j];
				}
				*(args[currentIndex] + size) = '\0';
				size = 0;
			}
		} else {
			size++;
		}
	}
	if (size > 0) {
		args[++currentIndex] = (char *) malloc ((size + 1) * sizeof(char));
		for (char j = 0; j < size; j++) {
			*(args[currentIndex] + j) = inputBuffer[lenght - size + j];
		}
		*(args[currentIndex] + size) = '\0';
	}
	*(elements) = currentIndex + 1;
}

void setup(char inputBuffer[], char *args[], int *background) {
	emptyPointerArray(args, MAX_ARGS);
    int len = read(STDIN_FILENO, inputBuffer, MAX_LINE);
    //Remove EOL
    inputBuffer[--len] = '\0';

	int nElements;
	splitStringBySpace(args, inputBuffer, &nElements);
	if (nElements > 0 && *(args[nElements - 1]) == '&') {
		args[nElements - 1] = NULL;
		*background = 1;
	}

	if (nElements > 0) {
		if (strcmp(args[0],"exit") == 0) {
			exit(0);
		} else if (strcmp(args[0],"r") == 0) {
			if (stackCounter > 0) {
				if (nElements > 1) {
					int i = findCommand(args[1]);
                    printf("%s\n", history[i]);
                    emptyPointerArray(args, MAX_ARGS);
					splitStringBySpace(args, history[i], &nElements);
				} else {
                    printf("%s\n", history[stackCounter - 1]);
					splitStringBySpace(args, history[stackCounter - 1], &nElements);
				}
			}
		}  else {
            pushToHistory(inputBuffer);
        }
	}
}

int main() {
	printf("Hello, that is the Xell V.1\n");
	printf("Galileo University, 2016.\n");
	printf("===========================\n");

	char inputBuffer[MAX_LINE];
	int background;
	char *args[MAX_ARGS] = {NULL};

    struct sigaction handler;
    handler.sa_flags = 0;
	handler.sa_handler = &showHistory;
	sigaction(SIGINT, &handler, NULL);

	while(1) {
		background = 0;
		printf("%s","baquiax@baquiax:$ \n");
		setup(inputBuffer, args, &background);
        if (strlen(inputBuffer) < 1){
            continue;
        }
		pid_t pid = fork();

		if (pid < 0) {
			printf("%s\n", "An error has been happened!");
		} else if (pid == 0) {
			execvp(args[0], args);
			exit(0);
		} else {
			if (!background) {
				wait(NULL);
			}
		}
	}
}

<commit_msg>Increasing limit of parameters;<commit_after>#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <sys/wait.h>

#define MAX_LINE 80
#define MAX_ARGS 40
#define MAX_HISTORY 10

char history[MAX_HISTORY][MAX_LINE] ;
char stackCounter;

void pushToHistory (char string[]) {
	if (stackCounter >= MAX_HISTORY) {
		//Move the stack
		for(char i = 1; i < MAX_HISTORY; i++) {
			strcpy(history[i - 1], history[i]);
		}
		stackCounter = MAX_HISTORY - 1;
	}
	strcpy(history[stackCounter], string);
	stackCounter++;
}

void printPointerArray(char *args[], char len) {
	printf("printArray > ARRAY LEN: %d\n", len);
	for (char i = 0; i < len; i++) {
		printf("[%d] %s\n", i, args[i]);
	}
}

void showHistory(int signum) {
    if (signum == SIGINT) {
        char message[] = "\n\nCurrent history: \n\n";
        write(STDOUT_FILENO, message, strlen(message));
        for (char i = 0; i < MAX_HISTORY; i++) {
            if (strlen(history[i])) {
                char command[85];
                sprintf(command, "%d %s\n",i + 1, history[i]);
                write(STDOUT_FILENO, command, strlen(command));
            } else {
                break;
            }
        }
    }
}

int findCommand(char initWith[]) {
    for (char i = 0; i < MAX_HISTORY; i++) {
        if (strlen(history[i])) {
            if(strncmp(history[i], initWith, strlen(initWith)) == 0) {
                return i;
            }
        } else {
            break;
        }
    }
    return -1;
}
void emptyPointerArray(char *args[], char len) {
	for (char i = 0; i < len; i++) {
		free(args[i]);
		args[i] = NULL;
	}
}

void splitStringBySpace(char *args[], char inputBuffer[], int *elements) {
	char currentIndex = -1;
	char size = 0;
	char lenght = strlen(inputBuffer);
	for (char i = 0 ; i < lenght ; i++) {
		if (inputBuffer[i] == ' ') {
			if (size > 0) {
				args[++currentIndex] = (char *) malloc ((size + 1) * sizeof(char));
				for (char j = 0; j < size; j++) {
					*(args[currentIndex] + j) = inputBuffer[i - size + j];
				}
				*(args[currentIndex] + size) = '\0';
				size = 0;
			}
		} else {
			size++;
		}
	}
	if (size > 0) {
		args[++currentIndex] = (char *) malloc ((size + 1) * sizeof(char));
		for (char j = 0; j < size; j++) {
			*(args[currentIndex] + j) = inputBuffer[lenght - size + j];
		}
		*(args[currentIndex] + size) = '\0';
	}
	*(elements) = currentIndex + 1;
}

void setup(char inputBuffer[], char *args[], int *background) {
	emptyPointerArray(args, MAX_ARGS);
    int len = read(STDIN_FILENO, inputBuffer, MAX_LINE);
    //Remove EOL
    inputBuffer[--len] = '\0';

	int nElements;
	splitStringBySpace(args, inputBuffer, &nElements);
	if (nElements > 0 && *(args[nElements - 1]) == '&') {
		args[nElements - 1] = NULL;
		*background = 1;
	}

	if (nElements > 0) {
		if (strcmp(args[0],"exit") == 0) {
			exit(0);
		} else if (strcmp(args[0],"r") == 0) {
			if (stackCounter > 0) {
				if (nElements > 1) {
					int i = findCommand(args[1]);
                    printf("%s\n", history[i]);
                    emptyPointerArray(args, MAX_ARGS);
					splitStringBySpace(args, history[i], &nElements);
				} else {
                    printf("%s\n", history[stackCounter - 1]);
					splitStringBySpace(args, history[stackCounter - 1], &nElements);
				}
			}
		}  else {
            pushToHistory(inputBuffer);
        }
	}
}

int main() {
	printf("Hello, that is the Xell V.1\n");
	printf("Galileo University, 2016.\n");
	printf("===========================\n");

	char inputBuffer[MAX_LINE];
	int background;
	char *args[MAX_ARGS] = {NULL};

    struct sigaction handler;
    handler.sa_flags = 0;
	handler.sa_handler = &showHistory;
	sigaction(SIGINT, &handler, NULL);

	while(1) {
		background = 0;
		printf("%s","baquiax@baquiax:$ \n");
		setup(inputBuffer, args, &background);
        if (strlen(inputBuffer) < 1){
            continue;
        }
		pid_t pid = fork();

		if (pid < 0) {
			printf("%s\n", "An error has been happened!");
		} else if (pid == 0) {
			execvp(args[0], args);
			exit(0);
		} else {
			if (!background) {
				wait(NULL);
			}
		}
	}
}

<|endoftext|>


<commit_before>#include "VideoStatisticsWidget.h"
#include "ui_VideoStatisticsWidget.h"

VideoStatisticsWidget::VideoStatisticsWidget(QWidget *parent)
    : QWidget(parent), ui(new Ui::VideoStatisticsWidget) {
    ui->setupUi(this);

    // redirect stream probe output to file (cannot read it in any other way
    // unfortunately)
    streamProbeProcess.setStandardOutputFile(PROBE_FILE_NAME);

    // react to frame probe output with parseFrameProbeOutput
    connect(&frameProbeProcess, &QProcess::readyRead, this,
            &VideoStatisticsWidget::parseFrameProbeOutput);

    // react to stream probe output with parseStreamProbeOutput
    connect(&streamProbeProcess, SIGNAL(finished(int, QProcess::ExitStatus)),
            this, SLOT(parseStreamProbeOutput(int, QProcess::ExitStatus)));

    // timer ze o ja pierdole
    interval = 100;
    timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(updateBitrate()));
    timer->start(interval);
    ui->lBitrate->setToolTip(paramManager.getHint("Bitrate"));
}

VideoStatisticsWidget::~VideoStatisticsWidget() { delete ui; }

void VideoStatisticsWidget::stopProbe() {
    frameProbeProcess.kill();
    streamProbeProcess.kill();
    frameProbeProcess.waitForFinished();
    streamProbeProcess.waitForFinished();
}

void VideoStatisticsWidget::parseFrameProbeOutput() {

    // read output line by line
    while (frameProbeProcess.canReadLine()) {
        QString output = frameProbeProcess.readLine();

        // find frame type
        if (output.startsWith("pict_type=")) {
            // put single character describing frame type into queue
            framesQueue.enqueue(output.toUtf8().constData()[10]);

            // throw out oldest frame types if over queue size limit
            if (framesQueue.size() > 16)
                stopProbe();
            // framesQueue.dequeue();

            // create snapshot of queue to display in widget
            QString framesQueueSnapshot;

            QListIterator<char> i(framesQueue);

            while (i.hasNext()) {
                framesQueueSnapshot.append(i.next());
            }

            ui->frameTypes->setText(framesQueueSnapshot);
        }

        // find frame width
        if (output.startsWith("width=")) {
            ui->frameWidth->setText(output.mid(6, output.length()));
        }

        // find frame height
        if (output.startsWith("height=")) {
            ui->frameHeight->setText(output.mid(7, output.length()));
        }
    }
}

void VideoStatisticsWidget::clearFrameQueue() {
    framesQueue.clear();
    ui->frameTypes->setText("");
}

void VideoStatisticsWidget::startFrameProbe(QString command) {
    frameProbeProcess.start(command);
}

void VideoStatisticsWidget::startStreamProbe(QString command) {
    streamProbeProcess.start(command);
}

void VideoStatisticsWidget::setFrameTypeText(QString text) {
    ui->frameTypes->setText(text);
}

void VideoStatisticsWidget::parseStreamProbeOutput(int a,
                                                   QProcess::ExitStatus b) {
    // to silence unused warning
    (void)a;
    (void)b;

    // read from data dumped into file
    std::ifstream myReadFile;
    myReadFile.open(PROBE_FILE_NAME.toUtf8().data());
    char output[100];
    if (myReadFile.is_open()) {
        while (!myReadFile.eof()) {

            myReadFile >> output;

            QString fileOutput = QString(output);

            // find frame rate
            if (fileOutput.startsWith("avg_frame_rate=")) {
                ui->frameRate->setText(fileOutput.mid(15, fileOutput.length()));
            }
        }
    } else {
        qDebug() << "ERROR: cannot access file";
    }
    myReadFile.close();
}

void VideoStatisticsWidget::onStatsChange(VlcStats *stats) {
    ui->decodedBlocks->setText(QString::number(stats->decoded_video));
    // ui->bitRate->setText(QString::number(stats->input_bitrate*10000));
    // bitrate is set in the another way
    ui->framesDropped->setText(QString::number(stats->lost_pictures));
    ui->bytesRead->setText(QString::number(stats->read_bytes / 100.0));
    ui->framesCount->setText(QString::number(stats->displayed_pictures));
}

QString VideoStatisticsWidget::getBitrate(QString line) {
    // QString bitrate;
    QRegExp rx = QRegExp(
        "avg_br=\\s*[0-9]+.?[0-9]+kbits/s"); // pobiera z avg_br= 29.9kbits/s
    QRegExp rx2 =
        QRegExp("[0-9]+.?[0-9]+kbits/s"); // sam bitrate czyli 29.9kbits/s
    QRegExp rx3 = QRegExp("out=\\s*[0-1]");
    rx3.indexIn(line);
    QString out = rx3.capturedTexts().at(0);
    // last line can be cut so it is needed to find a way to catch this case
    // properly(way below works but XDDD)
    if (out.length() < 1)
        return "";
    if (out[out.length() - 1] == '0')
        return "";
    rx.indexIn(line);
    rx2.indexIn(rx.capturedTexts().at(0));
    return rx2.capturedTexts().at(0);
}

void VideoStatisticsWidget::updateBitrate() {
    // XD
    QString bitrate = "dupa";
    QString prevBitrate = "kupa"; // to find last line with bitrate i check if
                                  // last read bitrate is not ""
    QFile inputFile(STATS_FILE_NAME);
    if (inputFile.open(QIODevice::ReadOnly)) {
        QTextStream in(&inputFile);
        while (!in.atEnd()) {
            QString line = in.readLine();
            prevBitrate =
                getBitrate(line); // getBitrate returns "" if line was bad
            if (prevBitrate != "") {
                bitrate = prevBitrate;
            }
            qDebug() << bitrate;
        }
    }
    inputFile.close();
    ui->bitRate->setText(bitrate);
}
<commit_msg>qdeubg delete - my bad<commit_after>#include "VideoStatisticsWidget.h"
#include "ui_VideoStatisticsWidget.h"

VideoStatisticsWidget::VideoStatisticsWidget(QWidget *parent)
    : QWidget(parent), ui(new Ui::VideoStatisticsWidget) {
    ui->setupUi(this);

    // redirect stream probe output to file (cannot read it in any other way
    // unfortunately)
    streamProbeProcess.setStandardOutputFile(PROBE_FILE_NAME);

    // react to frame probe output with parseFrameProbeOutput
    connect(&frameProbeProcess, &QProcess::readyRead, this,
            &VideoStatisticsWidget::parseFrameProbeOutput);

    // react to stream probe output with parseStreamProbeOutput
    connect(&streamProbeProcess, SIGNAL(finished(int, QProcess::ExitStatus)),
            this, SLOT(parseStreamProbeOutput(int, QProcess::ExitStatus)));

    // timer ze o ja pierdole
    interval = 100;
    timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(updateBitrate()));
    timer->start(interval);
    ui->lBitrate->setToolTip(paramManager.getHint("Bitrate"));
}

VideoStatisticsWidget::~VideoStatisticsWidget() { delete ui; }

void VideoStatisticsWidget::stopProbe() {
    frameProbeProcess.kill();
    streamProbeProcess.kill();
    frameProbeProcess.waitForFinished();
    streamProbeProcess.waitForFinished();
}

void VideoStatisticsWidget::parseFrameProbeOutput() {

    // read output line by line
    while (frameProbeProcess.canReadLine()) {
        QString output = frameProbeProcess.readLine();

        // find frame type
        if (output.startsWith("pict_type=")) {
            // put single character describing frame type into queue
            framesQueue.enqueue(output.toUtf8().constData()[10]);

            // throw out oldest frame types if over queue size limit
            if (framesQueue.size() > 16)
                stopProbe();
            // framesQueue.dequeue();

            // create snapshot of queue to display in widget
            QString framesQueueSnapshot;

            QListIterator<char> i(framesQueue);

            while (i.hasNext()) {
                framesQueueSnapshot.append(i.next());
            }

            ui->frameTypes->setText(framesQueueSnapshot);
        }

        // find frame width
        if (output.startsWith("width=")) {
            ui->frameWidth->setText(output.mid(6, output.length()));
        }

        // find frame height
        if (output.startsWith("height=")) {
            ui->frameHeight->setText(output.mid(7, output.length()));
        }
    }
}

void VideoStatisticsWidget::clearFrameQueue() {
    framesQueue.clear();
    ui->frameTypes->setText("");
}

void VideoStatisticsWidget::startFrameProbe(QString command) {
    frameProbeProcess.start(command);
}

void VideoStatisticsWidget::startStreamProbe(QString command) {
    streamProbeProcess.start(command);
}

void VideoStatisticsWidget::setFrameTypeText(QString text) {
    ui->frameTypes->setText(text);
}

void VideoStatisticsWidget::parseStreamProbeOutput(int a,
                                                   QProcess::ExitStatus b) {
    // to silence unused warning
    (void)a;
    (void)b;

    // read from data dumped into file
    std::ifstream myReadFile;
    myReadFile.open(PROBE_FILE_NAME.toUtf8().data());
    char output[100];
    if (myReadFile.is_open()) {
        while (!myReadFile.eof()) {

            myReadFile >> output;

            QString fileOutput = QString(output);

            // find frame rate
            if (fileOutput.startsWith("avg_frame_rate=")) {
                ui->frameRate->setText(fileOutput.mid(15, fileOutput.length()));
            }
        }
    } else {
        qDebug() << "ERROR: cannot access file";
    }
    myReadFile.close();
}

void VideoStatisticsWidget::onStatsChange(VlcStats *stats) {
    ui->decodedBlocks->setText(QString::number(stats->decoded_video));
    // ui->bitRate->setText(QString::number(stats->input_bitrate*10000));
    // bitrate is set in the another way
    ui->framesDropped->setText(QString::number(stats->lost_pictures));
    ui->bytesRead->setText(QString::number(stats->read_bytes / 100.0));
    ui->framesCount->setText(QString::number(stats->displayed_pictures));
}

QString VideoStatisticsWidget::getBitrate(QString line) {
    // QString bitrate;
    QRegExp rx = QRegExp(
        "avg_br=\\s*[0-9]+.?[0-9]+kbits/s"); // pobiera z avg_br= 29.9kbits/s
    QRegExp rx2 =
        QRegExp("[0-9]+.?[0-9]+kbits/s"); // sam bitrate czyli 29.9kbits/s
    QRegExp rx3 = QRegExp("out=\\s*[0-1]");
    rx3.indexIn(line);
    QString out = rx3.capturedTexts().at(0);
    // last line can be cut so it is needed to find a way to catch this case
    // properly(way below works but XDDD)
    if (out.length() < 1)
        return "";
    if (out[out.length() - 1] == '0')
        return "";
    rx.indexIn(line);
    rx2.indexIn(rx.capturedTexts().at(0));
    return rx2.capturedTexts().at(0);
}

void VideoStatisticsWidget::updateBitrate() {
    // XD
    QString bitrate = "dupa";
    QString prevBitrate = "kupa"; // to find last line with bitrate i check if
                                  // last read bitrate is not ""
    QFile inputFile(STATS_FILE_NAME);
    if (inputFile.open(QIODevice::ReadOnly)) {
        QTextStream in(&inputFile);
        while (!in.atEnd()) {
            QString line = in.readLine();
            prevBitrate =
                getBitrate(line); // getBitrate returns "" if line was bad
            if (prevBitrate != "") {
                bitrate = prevBitrate;
            }
        }
    }
    inputFile.close();
    ui->bitRate->setText(bitrate);
}
<|endoftext|>


<commit_before>#include "xchainer/array_repr.h"

#include <gtest/gtest.h>

#include <algorithm>
#include <cmath>
#include <limits>
#include <sstream>
#include <string>
#include <vector>

#include "xchainer/context.h"
#include "xchainer/device.h"
#include "xchainer/device_id.h"
#include "xchainer/native/native_backend.h"
#include "xchainer/native/native_device.h"
#include "xchainer/routines/creation.h"
#include "xchainer/testing/device_session.h"

namespace xchainer {
namespace {

template <typename T>
void CheckArrayRepr(
        const std::string& expected,
        const std::vector<T>& data_vec,
        Shape shape,
        Device& device,
        const std::vector<GraphId>& graph_ids = {}) {
    // Copy to a contiguous memory block because std::vector<bool> is not packed as a sequence of bool's.
    std::shared_ptr<T> data_ptr = std::make_unique<T[]>(data_vec.size());
    std::copy(data_vec.begin(), data_vec.end(), data_ptr.get());
    Array array = internal::FromContiguousHostData(shape, TypeToDtype<T>, static_cast<std::shared_ptr<void>>(data_ptr), device);
    for (const GraphId& graph_id : graph_ids) {
        array.RequireGrad(graph_id);
    }

    // std::string version
    EXPECT_EQ(expected, ArrayRepr(array));

    // std::ostream version
    std::ostringstream os;
    os << array;
    EXPECT_EQ(expected, os.str());
}

TEST(ArrayReprTest, AllDtypesOnNativeBackend) {
    testing::DeviceSession device_session{DeviceId{"native:0"}};
    Device& device = device_session.device();

    // bool
    CheckArrayRepr<bool>("array([False], shape=(1,), dtype=bool, device='native:0')", {false}, Shape({1}), device);
    CheckArrayRepr<bool>("array([ True], shape=(1,), dtype=bool, device='native:0')", {true}, Shape({1}), device);
    CheckArrayRepr<bool>(
            "array([[False,  True,  True],\n"
            "       [ True, False,  True]], shape=(2, 3), dtype=bool, device='native:0')",
            {false, true, true, true, false, true},
            Shape({2, 3}),
            device);
    CheckArrayRepr<bool>("array([[[[ True]]]], shape=(1, 1, 1, 1), dtype=bool, device='native:0')", {true}, Shape({1, 1, 1, 1}), device);

    // int8
    CheckArrayRepr<int8_t>("array([0], shape=(1,), dtype=int8, device='native:0')", {0}, Shape({1}), device);
    CheckArrayRepr<int8_t>("array([-2], shape=(1,), dtype=int8, device='native:0')", {-2}, Shape({1}), device);
    CheckArrayRepr<int8_t>(
            "array([[0, 1, 2],\n"
            "       [3, 4, 5]], shape=(2, 3), dtype=int8, device='native:0')",
            {0, 1, 2, 3, 4, 5},
            Shape({2, 3}),
            device);
    CheckArrayRepr<int8_t>(
            "array([[ 0,  1,  2],\n"
            "       [-3,  4,  5]], shape=(2, 3), dtype=int8, device='native:0')",
            {0, 1, 2, -3, 4, 5},
            Shape({2, 3}),
            device);
    CheckArrayRepr<int8_t>("array([[[[3]]]], shape=(1, 1, 1, 1), dtype=int8, device='native:0')", {3}, Shape({1, 1, 1, 1}), device);

    // int16
    CheckArrayRepr<int16_t>("array([0], shape=(1,), dtype=int16, device='native:0')", {0}, Shape({1}), device);
    CheckArrayRepr<int16_t>("array([-2], shape=(1,), dtype=int16, device='native:0')", {-2}, Shape({1}), device);
    CheckArrayRepr<int16_t>(
            "array([[0, 1, 2],\n"
            "       [3, 4, 5]], shape=(2, 3), dtype=int16, device='native:0')",
            {0, 1, 2, 3, 4, 5},
            Shape({2, 3}),
            device);
    CheckArrayRepr<int16_t>(
            "array([[ 0,  1,  2],\n"
            "       [-3,  4,  5]], shape=(2, 3), dtype=int16, device='native:0')",
            {0, 1, 2, -3, 4, 5},
            Shape({2, 3}),
            device);
    CheckArrayRepr<int16_t>("array([[[[3]]]], shape=(1, 1, 1, 1), dtype=int16, device='native:0')", {3}, Shape({1, 1, 1, 1}), device);

    // int32
    CheckArrayRepr<int32_t>("array([0], shape=(1,), dtype=int32, device='native:0')", {0}, Shape({1}), device);
    CheckArrayRepr<int32_t>("array([-2], shape=(1,), dtype=int32, device='native:0')", {-2}, Shape({1}), device);
    CheckArrayRepr<int32_t>(
            "array([[0, 1, 2],\n"
            "       [3, 4, 5]], shape=(2, 3), dtype=int32, device='native:0')",
            {0, 1, 2, 3, 4, 5},
            Shape({2, 3}),
            device);
    CheckArrayRepr<int32_t>(
            "array([[ 0,  1,  2],\n"
            "       [-3,  4,  5]], shape=(2, 3), dtype=int32, device='native:0')",
            {0, 1, 2, -3, 4, 5},
            Shape({2, 3}),
            device);
    CheckArrayRepr<int32_t>("array([[[[3]]]], shape=(1, 1, 1, 1), dtype=int32, device='native:0')", {3}, Shape({1, 1, 1, 1}), device);

    // int64
    CheckArrayRepr<int64_t>("array([0], shape=(1,), dtype=int64, device='native:0')", {0}, Shape({1}), device);
    CheckArrayRepr<int64_t>("array([-2], shape=(1,), dtype=int64, device='native:0')", {-2}, Shape({1}), device);
    CheckArrayRepr<int64_t>(
            "array([[0, 1, 2],\n"
            "       [3, 4, 5]], shape=(2, 3), dtype=int64, device='native:0')",
            {0, 1, 2, 3, 4, 5},
            Shape({2, 3}),
            device);
    CheckArrayRepr<int64_t>(
            "array([[ 0,  1,  2],\n"
            "       [-3,  4,  5]], shape=(2, 3), dtype=int64, device='native:0')",
            {0, 1, 2, -3, 4, 5},
            Shape({2, 3}),
            device);
    CheckArrayRepr<int64_t>("array([[[[3]]]], shape=(1, 1, 1, 1), dtype=int64, device='native:0')", {3}, Shape({1, 1, 1, 1}), device);

    // uint8
    CheckArrayRepr<uint8_t>("array([0], shape=(1,), dtype=uint8, device='native:0')", {0}, Shape({1}), device);
    CheckArrayRepr<uint8_t>("array([2], shape=(1,), dtype=uint8, device='native:0')", {2}, Shape({1}), device);
    CheckArrayRepr<uint8_t>(
            "array([[0, 1, 2],\n"
            "       [3, 4, 5]], shape=(2, 3), dtype=uint8, device='native:0')",
            {0, 1, 2, 3, 4, 5},
            Shape({2, 3}),
            device);
    CheckArrayRepr<uint8_t>("array([[[[3]]]], shape=(1, 1, 1, 1), dtype=uint8, device='native:0')", {3}, Shape({1, 1, 1, 1}), device);

    // float32
    CheckArrayRepr<float>("array([0.], shape=(1,), dtype=float32, device='native:0')", {0}, Shape({1}), device);
    CheckArrayRepr<float>("array([3.25], shape=(1,), dtype=float32, device='native:0')", {3.25}, Shape({1}), device);
    CheckArrayRepr<float>("array([-3.25], shape=(1,), dtype=float32, device='native:0')", {-3.25}, Shape({1}), device);
    CheckArrayRepr<float>(
            "array([ inf], shape=(1,), dtype=float32, device='native:0')", {std::numeric_limits<float>::infinity()}, Shape({1}), device);
    CheckArrayRepr<float>(
            "array([ -inf], shape=(1,), dtype=float32, device='native:0')", {-std::numeric_limits<float>::infinity()}, Shape({1}), device);
    CheckArrayRepr<float>("array([ nan], shape=(1,), dtype=float32, device='native:0')", {std::nanf("")}, Shape({1}), device);
    CheckArrayRepr<float>(
            "array([[0., 1., 2.],\n"
            "       [3., 4., 5.]], shape=(2, 3), dtype=float32, device='native:0')",
            {0, 1, 2, 3, 4, 5},
            Shape({2, 3}),
            device);
    CheckArrayRepr<float>(
            "array([[0.  , 1.  , 2.  ],\n"
            "       [3.25, 4.  , 5.  ]], shape=(2, 3), dtype=float32, device='native:0')",
            {0, 1, 2, 3.25, 4, 5},
            Shape({2, 3}),
            device);
    CheckArrayRepr<float>(
            "array([[ 0.  ,  1.  ,  2.  ],\n"
            "       [-3.25,  4.  ,  5.  ]], shape=(2, 3), dtype=float32, device='native:0')",
            {0, 1, 2, -3.25, 4, 5},
            Shape({2, 3}),
            device);
    CheckArrayRepr<float>("array([[[[3.25]]]], shape=(1, 1, 1, 1), dtype=float32, device='native:0')", {3.25}, Shape({1, 1, 1, 1}), device);

    // float64
    CheckArrayRepr<double>("array([0.], shape=(1,), dtype=float64, device='native:0')", {0}, Shape({1}), device);
    CheckArrayRepr<double>("array([3.25], shape=(1,), dtype=float64, device='native:0')", {3.25}, Shape({1}), device);
    CheckArrayRepr<double>("array([-3.25], shape=(1,), dtype=float64, device='native:0')", {-3.25}, Shape({1}), device);
    CheckArrayRepr<double>(
            "array([ inf], shape=(1,), dtype=float64, device='native:0')", {std::numeric_limits<double>::infinity()}, Shape({1}), device);
    CheckArrayRepr<double>(
            "array([ -inf], shape=(1,), dtype=float64, device='native:0')", {-std::numeric_limits<double>::infinity()}, Shape({1}), device);
    CheckArrayRepr<double>("array([ nan], shape=(1,), dtype=float64, device='native:0')", {std::nan("")}, Shape({1}), device);
    CheckArrayRepr<double>(
            "array([[0., 1., 2.],\n"
            "       [3., 4., 5.]], shape=(2, 3), dtype=float64, device='native:0')",
            {0, 1, 2, 3, 4, 5},
            Shape({2, 3}),
            device);
    CheckArrayRepr<double>(
            "array([[0.  , 1.  , 2.  ],\n"
            "       [3.25, 4.  , 5.  ]], shape=(2, 3), dtype=float64, device='native:0')",
            {0, 1, 2, 3.25, 4, 5},
            Shape({2, 3}),
            device);
    CheckArrayRepr<double>(
            "array([[ 0.  ,  1.  ,  2.  ],\n"
            "       [-3.25,  4.  ,  5.  ]], shape=(2, 3), dtype=float64, device='native:0')",
            {0, 1, 2, -3.25, 4, 5},
            Shape({2, 3}),
            device);
    CheckArrayRepr<double>(
            "array([[[[3.25]]]], shape=(1, 1, 1, 1), dtype=float64, device='native:0')", {3.25}, Shape({1, 1, 1, 1}), device);

    // 0-sized
    CheckArrayRepr<int32_t>(
            "array([], shape=(0, 1, 2), dtype=int32, device='native:0', graph_ids=['graph_1'])", {}, Shape({0, 1, 2}), device, {"graph_1"});

    // Single graph
    CheckArrayRepr<int32_t>(
            "array([-2], shape=(1,), dtype=int32, device='native:0', graph_ids=['graph_1'])", {-2}, Shape({1}), device, {"graph_1"});

    // Two graphs
    CheckArrayRepr<int32_t>(
            "array([1], shape=(1,), dtype=int32, device='native:0', graph_ids=['graph_1', 'graph_2'])",
            {1},
            Shape({1}),
            device,
            {"graph_1", "graph_2"});

    // Multiple graphs
    CheckArrayRepr<int32_t>(
            "array([-9], shape=(1,), dtype=int32, device='native:0', graph_ids=['graph_1', 'graph_2', 'graph_3', 'graph_4', 'graph_5'])",
            {-9},
            Shape({1}),
            device,
            {"graph_1", "graph_2", "graph_3", "graph_4", "graph_5"});
}

}  // namespace
}  // namespace xchainer
<commit_msg>clang-tidy<commit_after>#include "xchainer/array_repr.h"

#include <gtest/gtest.h>

#include <algorithm>
#include <cmath>
#include <limits>
#include <sstream>
#include <string>
#include <vector>

#include "xchainer/context.h"
#include "xchainer/device.h"
#include "xchainer/device_id.h"
#include "xchainer/native/native_backend.h"
#include "xchainer/native/native_device.h"
#include "xchainer/routines/creation.h"
#include "xchainer/testing/device_session.h"

namespace xchainer {
namespace {

template <typename T>
void CheckArrayRepr(
        const std::string& expected,
        const std::vector<T>& data_vec,
        const Shape& shape,
        Device& device,
        const std::vector<GraphId>& graph_ids = {}) {
    // Copy to a contiguous memory block because std::vector<bool> is not packed as a sequence of bool's.
    std::shared_ptr<T> data_ptr = std::make_unique<T[]>(data_vec.size());
    std::copy(data_vec.begin(), data_vec.end(), data_ptr.get());
    Array array = internal::FromContiguousHostData(shape, TypeToDtype<T>, static_cast<std::shared_ptr<void>>(data_ptr), device);
    for (const GraphId& graph_id : graph_ids) {
        array.RequireGrad(graph_id);
    }

    // std::string version
    EXPECT_EQ(expected, ArrayRepr(array));

    // std::ostream version
    std::ostringstream os;
    os << array;
    EXPECT_EQ(expected, os.str());
}

TEST(ArrayReprTest, AllDtypesOnNativeBackend) {
    testing::DeviceSession device_session{DeviceId{"native:0"}};
    Device& device = device_session.device();

    // bool
    CheckArrayRepr<bool>("array([False], shape=(1,), dtype=bool, device='native:0')", {false}, Shape({1}), device);
    CheckArrayRepr<bool>("array([ True], shape=(1,), dtype=bool, device='native:0')", {true}, Shape({1}), device);
    CheckArrayRepr<bool>(
            "array([[False,  True,  True],\n"
            "       [ True, False,  True]], shape=(2, 3), dtype=bool, device='native:0')",
            {false, true, true, true, false, true},
            Shape({2, 3}),
            device);
    CheckArrayRepr<bool>("array([[[[ True]]]], shape=(1, 1, 1, 1), dtype=bool, device='native:0')", {true}, Shape({1, 1, 1, 1}), device);

    // int8
    CheckArrayRepr<int8_t>("array([0], shape=(1,), dtype=int8, device='native:0')", {0}, Shape({1}), device);
    CheckArrayRepr<int8_t>("array([-2], shape=(1,), dtype=int8, device='native:0')", {-2}, Shape({1}), device);
    CheckArrayRepr<int8_t>(
            "array([[0, 1, 2],\n"
            "       [3, 4, 5]], shape=(2, 3), dtype=int8, device='native:0')",
            {0, 1, 2, 3, 4, 5},
            Shape({2, 3}),
            device);
    CheckArrayRepr<int8_t>(
            "array([[ 0,  1,  2],\n"
            "       [-3,  4,  5]], shape=(2, 3), dtype=int8, device='native:0')",
            {0, 1, 2, -3, 4, 5},
            Shape({2, 3}),
            device);
    CheckArrayRepr<int8_t>("array([[[[3]]]], shape=(1, 1, 1, 1), dtype=int8, device='native:0')", {3}, Shape({1, 1, 1, 1}), device);

    // int16
    CheckArrayRepr<int16_t>("array([0], shape=(1,), dtype=int16, device='native:0')", {0}, Shape({1}), device);
    CheckArrayRepr<int16_t>("array([-2], shape=(1,), dtype=int16, device='native:0')", {-2}, Shape({1}), device);
    CheckArrayRepr<int16_t>(
            "array([[0, 1, 2],\n"
            "       [3, 4, 5]], shape=(2, 3), dtype=int16, device='native:0')",
            {0, 1, 2, 3, 4, 5},
            Shape({2, 3}),
            device);
    CheckArrayRepr<int16_t>(
            "array([[ 0,  1,  2],\n"
            "       [-3,  4,  5]], shape=(2, 3), dtype=int16, device='native:0')",
            {0, 1, 2, -3, 4, 5},
            Shape({2, 3}),
            device);
    CheckArrayRepr<int16_t>("array([[[[3]]]], shape=(1, 1, 1, 1), dtype=int16, device='native:0')", {3}, Shape({1, 1, 1, 1}), device);

    // int32
    CheckArrayRepr<int32_t>("array([0], shape=(1,), dtype=int32, device='native:0')", {0}, Shape({1}), device);
    CheckArrayRepr<int32_t>("array([-2], shape=(1,), dtype=int32, device='native:0')", {-2}, Shape({1}), device);
    CheckArrayRepr<int32_t>(
            "array([[0, 1, 2],\n"
            "       [3, 4, 5]], shape=(2, 3), dtype=int32, device='native:0')",
            {0, 1, 2, 3, 4, 5},
            Shape({2, 3}),
            device);
    CheckArrayRepr<int32_t>(
            "array([[ 0,  1,  2],\n"
            "       [-3,  4,  5]], shape=(2, 3), dtype=int32, device='native:0')",
            {0, 1, 2, -3, 4, 5},
            Shape({2, 3}),
            device);
    CheckArrayRepr<int32_t>("array([[[[3]]]], shape=(1, 1, 1, 1), dtype=int32, device='native:0')", {3}, Shape({1, 1, 1, 1}), device);

    // int64
    CheckArrayRepr<int64_t>("array([0], shape=(1,), dtype=int64, device='native:0')", {0}, Shape({1}), device);
    CheckArrayRepr<int64_t>("array([-2], shape=(1,), dtype=int64, device='native:0')", {-2}, Shape({1}), device);
    CheckArrayRepr<int64_t>(
            "array([[0, 1, 2],\n"
            "       [3, 4, 5]], shape=(2, 3), dtype=int64, device='native:0')",
            {0, 1, 2, 3, 4, 5},
            Shape({2, 3}),
            device);
    CheckArrayRepr<int64_t>(
            "array([[ 0,  1,  2],\n"
            "       [-3,  4,  5]], shape=(2, 3), dtype=int64, device='native:0')",
            {0, 1, 2, -3, 4, 5},
            Shape({2, 3}),
            device);
    CheckArrayRepr<int64_t>("array([[[[3]]]], shape=(1, 1, 1, 1), dtype=int64, device='native:0')", {3}, Shape({1, 1, 1, 1}), device);

    // uint8
    CheckArrayRepr<uint8_t>("array([0], shape=(1,), dtype=uint8, device='native:0')", {0}, Shape({1}), device);
    CheckArrayRepr<uint8_t>("array([2], shape=(1,), dtype=uint8, device='native:0')", {2}, Shape({1}), device);
    CheckArrayRepr<uint8_t>(
            "array([[0, 1, 2],\n"
            "       [3, 4, 5]], shape=(2, 3), dtype=uint8, device='native:0')",
            {0, 1, 2, 3, 4, 5},
            Shape({2, 3}),
            device);
    CheckArrayRepr<uint8_t>("array([[[[3]]]], shape=(1, 1, 1, 1), dtype=uint8, device='native:0')", {3}, Shape({1, 1, 1, 1}), device);

    // float32
    CheckArrayRepr<float>("array([0.], shape=(1,), dtype=float32, device='native:0')", {0}, Shape({1}), device);
    CheckArrayRepr<float>("array([3.25], shape=(1,), dtype=float32, device='native:0')", {3.25}, Shape({1}), device);
    CheckArrayRepr<float>("array([-3.25], shape=(1,), dtype=float32, device='native:0')", {-3.25}, Shape({1}), device);
    CheckArrayRepr<float>(
            "array([ inf], shape=(1,), dtype=float32, device='native:0')", {std::numeric_limits<float>::infinity()}, Shape({1}), device);
    CheckArrayRepr<float>(
            "array([ -inf], shape=(1,), dtype=float32, device='native:0')", {-std::numeric_limits<float>::infinity()}, Shape({1}), device);
    CheckArrayRepr<float>("array([ nan], shape=(1,), dtype=float32, device='native:0')", {std::nanf("")}, Shape({1}), device);
    CheckArrayRepr<float>(
            "array([[0., 1., 2.],\n"
            "       [3., 4., 5.]], shape=(2, 3), dtype=float32, device='native:0')",
            {0, 1, 2, 3, 4, 5},
            Shape({2, 3}),
            device);
    CheckArrayRepr<float>(
            "array([[0.  , 1.  , 2.  ],\n"
            "       [3.25, 4.  , 5.  ]], shape=(2, 3), dtype=float32, device='native:0')",
            {0, 1, 2, 3.25, 4, 5},
            Shape({2, 3}),
            device);
    CheckArrayRepr<float>(
            "array([[ 0.  ,  1.  ,  2.  ],\n"
            "       [-3.25,  4.  ,  5.  ]], shape=(2, 3), dtype=float32, device='native:0')",
            {0, 1, 2, -3.25, 4, 5},
            Shape({2, 3}),
            device);
    CheckArrayRepr<float>("array([[[[3.25]]]], shape=(1, 1, 1, 1), dtype=float32, device='native:0')", {3.25}, Shape({1, 1, 1, 1}), device);

    // float64
    CheckArrayRepr<double>("array([0.], shape=(1,), dtype=float64, device='native:0')", {0}, Shape({1}), device);
    CheckArrayRepr<double>("array([3.25], shape=(1,), dtype=float64, device='native:0')", {3.25}, Shape({1}), device);
    CheckArrayRepr<double>("array([-3.25], shape=(1,), dtype=float64, device='native:0')", {-3.25}, Shape({1}), device);
    CheckArrayRepr<double>(
            "array([ inf], shape=(1,), dtype=float64, device='native:0')", {std::numeric_limits<double>::infinity()}, Shape({1}), device);
    CheckArrayRepr<double>(
            "array([ -inf], shape=(1,), dtype=float64, device='native:0')", {-std::numeric_limits<double>::infinity()}, Shape({1}), device);
    CheckArrayRepr<double>("array([ nan], shape=(1,), dtype=float64, device='native:0')", {std::nan("")}, Shape({1}), device);
    CheckArrayRepr<double>(
            "array([[0., 1., 2.],\n"
            "       [3., 4., 5.]], shape=(2, 3), dtype=float64, device='native:0')",
            {0, 1, 2, 3, 4, 5},
            Shape({2, 3}),
            device);
    CheckArrayRepr<double>(
            "array([[0.  , 1.  , 2.  ],\n"
            "       [3.25, 4.  , 5.  ]], shape=(2, 3), dtype=float64, device='native:0')",
            {0, 1, 2, 3.25, 4, 5},
            Shape({2, 3}),
            device);
    CheckArrayRepr<double>(
            "array([[ 0.  ,  1.  ,  2.  ],\n"
            "       [-3.25,  4.  ,  5.  ]], shape=(2, 3), dtype=float64, device='native:0')",
            {0, 1, 2, -3.25, 4, 5},
            Shape({2, 3}),
            device);
    CheckArrayRepr<double>(
            "array([[[[3.25]]]], shape=(1, 1, 1, 1), dtype=float64, device='native:0')", {3.25}, Shape({1, 1, 1, 1}), device);

    // 0-sized
    CheckArrayRepr<int32_t>(
            "array([], shape=(0, 1, 2), dtype=int32, device='native:0', graph_ids=['graph_1'])", {}, Shape({0, 1, 2}), device, {"graph_1"});

    // Single graph
    CheckArrayRepr<int32_t>(
            "array([-2], shape=(1,), dtype=int32, device='native:0', graph_ids=['graph_1'])", {-2}, Shape({1}), device, {"graph_1"});

    // Two graphs
    CheckArrayRepr<int32_t>(
            "array([1], shape=(1,), dtype=int32, device='native:0', graph_ids=['graph_1', 'graph_2'])",
            {1},
            Shape({1}),
            device,
            {"graph_1", "graph_2"});

    // Multiple graphs
    CheckArrayRepr<int32_t>(
            "array([-9], shape=(1,), dtype=int32, device='native:0', graph_ids=['graph_1', 'graph_2', 'graph_3', 'graph_4', 'graph_5'])",
            {-9},
            Shape({1}),
            device,
            {"graph_1", "graph_2", "graph_3", "graph_4", "graph_5"});
}

}  // namespace
}  // namespace xchainer
<|endoftext|>


<commit_before>/******************************************************************************
 *                    _   _____   __________                                  *
 *                   | | / / _ | / __/_  __/     Visibility                   *
 *                   | |/ / __ |_\ \  / /          Across                     *
 *                   |___/_/ |_/___/ /_/       Space and Time                 *
 *                                                                            *
 * This file is part of VAST. It is subject to the license terms in the       *
 * LICENSE file found in the top-level directory of this distribution and at  *
 * http://vast.io/license. No part of VAST, including this file, may be       *
 * copied, modified, propagated, or distributed except according to the terms *
 * contained in the LICENSE file.                                             *
 ******************************************************************************/

#pragma once

#include "vast/concept/parseable/core.hpp"
#include "vast/concept/parseable/string/char_class.hpp"
#include "vast/concept/parseable/vast/data.hpp"
#include "vast/concept/parseable/vast/type.hpp"
#include "vast/data.hpp"
#include "vast/expression.hpp"
#include "vast/type.hpp"

#include "vast/detail/assert.hpp"
#include "vast/detail/string.hpp"

namespace vast {

struct predicate_parser : parser<predicate_parser> {
  using attribute = predicate;

  using predicate_tuple = std::tuple<predicate::operand, relational_operator,
                                     predicate::operand>;

  static predicate to_predicate(predicate_tuple xs);

  static predicate::operand to_key_extractor(std::vector<std::string> xs);

  static predicate::operand to_attr_extractor(std::string x);

  static predicate::operand to_type_extractor(type x);

  static predicate::operand to_data_operand(data x);

  static predicate to_data_predicate(data x);

  static auto make() {
    // clang-format off
    using parsers::alnum;
    using parsers::chr;
    using namespace parser_literals;
    auto id = +(alnum | chr{'_'} | chr{'-'});
    // A key cannot start with ':', othwise it would be interpreted as a type
    // extractor.
    auto key = !':'_p >> (+(alnum | chr{'_'} | chr{':'}) % '.');
    auto operand
      = parsers::data ->* to_data_operand
      | '#' >> id ->* to_attr_extractor
      | ':' >> parsers::type ->* to_type_extractor
      | key ->* to_key_extractor
      ;
    auto operation
      = "~"_p   ->* [] { return match; }
      | "!~"_p  ->* [] { return not_match; }
      | "=="_p  ->* [] { return equal; }
      | "!="_p  ->* [] { return not_equal; }
      | "<="_p  ->* [] { return less_equal; }
      | "<"_p   ->* [] { return less; }
      | ">="_p  ->* [] { return greater_equal; }
      | ">"_p   ->* [] { return greater; }
      | "in"_p  ->* [] { return in; }
      | "!in"_p ->* [] { return not_in; }
      | "ni"_p  ->* [] { return ni; }
      | "!ni"_p ->* [] { return not_ni; }
      | "[+"_p  ->* [] { return in; }
      | "[-"_p  ->* [] { return not_in; }
      | "+]"_p  ->* [] { return ni; }
      | "-]"_p  ->* [] { return not_ni; }
      ;
    auto ws = ignore(*parsers::space);
    auto pred
      = (operand >> ws >> operation >> ws >> operand) ->* to_predicate
      | parsers::data ->* to_data_predicate;
      ;
    return pred;
    // clang-format on
  }

  template <class Iterator>
  bool parse(Iterator& f, const Iterator& l, unused_type) const {
    static auto p = make();
    return p(f, l, unused);
  }

  template <class Iterator>
  bool parse(Iterator& f, const Iterator& l, predicate& a) const {
    using namespace parsers;
    static auto p = make();
    return p(f, l, a);
  }
};

template <>
struct parser_registry<predicate> {
  using type = predicate_parser;
};

namespace parsers {

static auto const predicate = make_parser<vast::predicate>();

} // namespace parsers

struct expression_parser : parser<expression_parser> {
  using attribute = expression;

  template <class Iterator>
  static auto make() {
    using namespace parser_literals;
    using chain = std::vector<std::tuple<bool_operator, expression>>;
    using raw_expr = std::tuple<expression, chain>;
    // Converts a "raw" chain of sub-expressions and transforms it into an
    // expression tree.
    auto to_expr = [](raw_expr expr) -> expression {
      auto& [x, xs] = expr;
      if (xs.empty())
        return x;
      // We split the expression chain at each OR node in order to take care of
      // operator precedance: AND binds stronger than OR.
      disjunction dis;
      auto con = conjunction{x};
      for (auto& [op, expr] : xs)
        if (op == logical_and) {
          con.emplace_back(std::move(expr));
        } else if (op == logical_or) {
          VAST_ASSERT(!con.empty());
          if (con.size() == 1)
            dis.emplace_back(std::move(con[0]));
          else
            dis.emplace_back(std::move(con));
          con = conjunction{std::move(expr)};
        } else {
          VAST_ASSERT(!"negations must not exist here");
        }
      if (con.size() == 1)
        dis.emplace_back(std::move(con[0]));
      else
        dis.emplace_back(std::move(con));
      return dis.size() == 1 ? std::move(dis[0]) : expression{dis};
    };
    auto ws = ignore(*parsers::space);
    auto negate_pred = [](predicate p) { return negation{expression{p}}; };
    auto negate_expr = [](expression expr) { return negation{expr}; };
    rule<Iterator, expression> expr;
    rule<Iterator, expression> group;
    // clang-format off
    group
      = '(' >> ws >> expr >> ws >> ')'
      | '!' >> ws >> parsers::predicate ->* negate_pred
      | '!' >> ws >> '(' >> ws >> (expr ->* negate_expr) >> ws >> ')'
      | parsers::predicate
      ;
    auto and_or
      = "||"_p  ->* [] { return logical_or; }
      | "&&"_p  ->* [] { return logical_and; }
      ;
    expr
      = ((group >> *(ws >> and_or >> ws >> group)) ->* to_expr)
      >> ws >> parsers::eoi
      ;
    // clang-format on
    return expr;
  }

  template <class Iterator>
  bool parse(Iterator& f, const Iterator& l, unused_type) const {
    static auto p = make<Iterator>();
    return p(f, l, unused);
  }

  template <class Iterator>
  bool parse(Iterator& f, const Iterator& l, expression& a) const {
    static auto p = make<Iterator>();
    return p(f, l, a);
  }
};

template <>
struct parser_registry<expression> {
  using type = expression_parser;
};

namespace parsers {

static auto const expr = make_parser<vast::expression>();

} // namespace parsers
} // namespace vast
<commit_msg>Fix UB in expression parser eoi check<commit_after>/******************************************************************************
 *                    _   _____   __________                                  *
 *                   | | / / _ | / __/_  __/     Visibility                   *
 *                   | |/ / __ |_\ \  / /          Across                     *
 *                   |___/_/ |_/___/ /_/       Space and Time                 *
 *                                                                            *
 * This file is part of VAST. It is subject to the license terms in the       *
 * LICENSE file found in the top-level directory of this distribution and at  *
 * http://vast.io/license. No part of VAST, including this file, may be       *
 * copied, modified, propagated, or distributed except according to the terms *
 * contained in the LICENSE file.                                             *
 ******************************************************************************/

#pragma once

#include "vast/concept/parseable/core.hpp"
#include "vast/concept/parseable/string/char_class.hpp"
#include "vast/concept/parseable/vast/data.hpp"
#include "vast/concept/parseable/vast/type.hpp"
#include "vast/data.hpp"
#include "vast/detail/assert.hpp"
#include "vast/detail/string.hpp"
#include "vast/expression.hpp"
#include "vast/type.hpp"

namespace vast {

struct predicate_parser : parser<predicate_parser> {
  using attribute = predicate;

  using predicate_tuple = std::tuple<predicate::operand, relational_operator,
                                     predicate::operand>;

  static predicate to_predicate(predicate_tuple xs);

  static predicate::operand to_key_extractor(std::vector<std::string> xs);

  static predicate::operand to_attr_extractor(std::string x);

  static predicate::operand to_type_extractor(type x);

  static predicate::operand to_data_operand(data x);

  static predicate to_data_predicate(data x);

  static auto make() {
    // clang-format off
    using parsers::alnum;
    using parsers::chr;
    using namespace parser_literals;
    auto id = +(alnum | chr{'_'} | chr{'-'});
    // A key cannot start with ':', othwise it would be interpreted as a type
    // extractor.
    auto key = !':'_p >> (+(alnum | chr{'_'} | chr{':'}) % '.');
    auto operand
      = parsers::data ->* to_data_operand
      | '#' >> id ->* to_attr_extractor
      | ':' >> parsers::type ->* to_type_extractor
      | key ->* to_key_extractor
      ;
    auto operation
      = "~"_p   ->* [] { return match; }
      | "!~"_p  ->* [] { return not_match; }
      | "=="_p  ->* [] { return equal; }
      | "!="_p  ->* [] { return not_equal; }
      | "<="_p  ->* [] { return less_equal; }
      | "<"_p   ->* [] { return less; }
      | ">="_p  ->* [] { return greater_equal; }
      | ">"_p   ->* [] { return greater; }
      | "in"_p  ->* [] { return in; }
      | "!in"_p ->* [] { return not_in; }
      | "ni"_p  ->* [] { return ni; }
      | "!ni"_p ->* [] { return not_ni; }
      | "[+"_p  ->* [] { return in; }
      | "[-"_p  ->* [] { return not_in; }
      | "+]"_p  ->* [] { return ni; }
      | "-]"_p  ->* [] { return not_ni; }
      ;
    auto ws = ignore(*parsers::space);
    auto pred
      = (operand >> ws >> operation >> ws >> operand) ->* to_predicate
      | parsers::data ->* to_data_predicate;
      ;
    return pred;
    // clang-format on
  }

  template <class Iterator>
  bool parse(Iterator& f, const Iterator& l, unused_type) const {
    static auto p = make();
    return p(f, l, unused);
  }

  template <class Iterator>
  bool parse(Iterator& f, const Iterator& l, predicate& a) const {
    using namespace parsers;
    static auto p = make();
    return p(f, l, a);
  }
};

template <>
struct parser_registry<predicate> {
  using type = predicate_parser;
};

namespace parsers {

static auto const predicate = make_parser<vast::predicate>();

} // namespace parsers

struct expression_parser : parser<expression_parser> {
  using attribute = expression;

  template <class Iterator>
  static auto make() {
    using namespace parser_literals;
    using chain = std::vector<std::tuple<bool_operator, expression>>;
    using raw_expr = std::tuple<expression, chain>;
    // Converts a "raw" chain of sub-expressions and transforms it into an
    // expression tree.
    auto to_expr = [](raw_expr expr) -> expression {
      auto& [x, xs] = expr;
      if (xs.empty())
        return x;
      // We split the expression chain at each OR node in order to take care of
      // operator precedance: AND binds stronger than OR.
      disjunction dis;
      auto con = conjunction{x};
      for (auto& [op, expr] : xs)
        if (op == logical_and) {
          con.emplace_back(std::move(expr));
        } else if (op == logical_or) {
          VAST_ASSERT(!con.empty());
          if (con.size() == 1)
            dis.emplace_back(std::move(con[0]));
          else
            dis.emplace_back(std::move(con));
          con = conjunction{std::move(expr)};
        } else {
          VAST_ASSERT(!"negations must not exist here");
        }
      if (con.size() == 1)
        dis.emplace_back(std::move(con[0]));
      else
        dis.emplace_back(std::move(con));
      return dis.size() == 1 ? std::move(dis[0]) : expression{dis};
    };
    auto ws = ignore(*parsers::space);
    auto negate_pred = [](predicate p) { return negation{expression{p}}; };
    auto negate_expr = [](expression expr) { return negation{expr}; };
    rule<Iterator, expression> expr;
    rule<Iterator, expression> group;
    // clang-format off
    group
      = '(' >> ws >> expr >> ws >> ')'
      | '!' >> ws >> parsers::predicate ->* negate_pred
      | '!' >> ws >> '(' >> ws >> (expr ->* negate_expr) >> ws >> ')'
      | parsers::predicate
      ;
    auto and_or
      = "||"_p  ->* [] { return logical_or; }
      | "&&"_p  ->* [] { return logical_and; }
      ;
    expr
      = (group >> *(ws >> and_or >> ws >> group) >> ws) ->* to_expr
      ;
    // clang-format on
    return expr >> parsers::eoi;
  }

  template <class Iterator, class Attribute>
  bool parse(Iterator& f, const Iterator& l, Attribute& x) const {
    static auto p = make<Iterator>();
    return p(f, l, x);
  }
};

template <>
struct parser_registry<expression> {
  using type = expression_parser;
};

namespace parsers {

static auto const expr = make_parser<vast::expression>();

} // namespace parsers
} // namespace vast
<|endoftext|>