<commit_before>#ifndef	types_h
#define types_h
#include <boost/variant.hpp>
#include <vector>
#include <string>
#include <functional>

namespace doanimate {
	namespace types {
		namespace implementation {
			class type_info;
		}

		implementation::type_info simplify(const implementation::type_info);

		namespace implementation {
			enum type_info_enum {
				boolean,
				integer,
				number,
				list,
				tuple,
				generic,
				function,
				code,
				specialize,
				any,
				string
			};

			class type_info {
				type_info_enum category;
				type_info* single_extension = nullptr;
				std::vector<type_info> first_group = {};
				std::vector<type_info> second_group = {};
				size_t generic_index = 0;
				std::string lbl = "";

				inline type_info(const type_info_enum cat) : category(cat) {
				}

				inline type_info(const type_info_enum cat, type_info ext) : category(cat), single_extension(new type_info(ext)) {
				}

				inline type_info(const type_info_enum cat, std::vector<type_info> group) : category(cat), first_group(group) {
				}

				inline type_info(const type_info_enum cat, type_info ext, std::vector<type_info> group)
				: category(cat), single_extension(new type_info(ext)), first_group(group) {
				}

				inline type_info(const type_info_enum cat, std::vector<type_info> first, std::vector<type_info> second)
				: category(cat), first_group(first), second_group(second) {
				}

				inline type_info(const type_info_enum cat, type_info ext, std::vector<type_info> first, std::vector<type_info> second)
				: category(cat), single_extension(new type_info(ext)), first_group(first), second_group(second) {
				}

				inline type_info(const size_t index) : category(type_info_enum::generic), generic_index(index) {
				}

				inline type_info(const type_info other, const std::string lbl)
				: category(other.category), single_extension(other.single_extension), first_group(other.first_group),
				  second_group(other.second_group), generic_index(other.generic_index), lbl(lbl) {
				}

				public:
				inline type_info() : type_info(type_info_enum::tuple) {
				}

				inline bool operator==(const type_info other) const {
					type_info a = simplify(*this);
					type_info b = simplify(other);
					if (a.category != b.category)
						return false;
					if (a.single_extension != nullptr)
						if (b.single_extension != nullptr)
							if (*a.single_extension != *b.single_extension)
								return false;
							else;
						else
							return false;
					else
						if (b.single_extension == nullptr)
							return false;
					if (a.first_group != b.first_group)
						return false;
					if (a.second_group != b.second_group)
						return false;
					if (a.generic_index != b.generic_index)
						return false;
					if (a.lbl != b.lbl)
						return false;
					return true;
				}

				inline bool operator!=(const type_info other) const {
					return not (*this == other);
				}

				inline bool is_equivalent(const type_info other) const {
					type_info a = simplify(*this);
					type_info b = simplify(other);
					if (a.category != b.category)
						return false;
					if (a.single_extension != nullptr)
						if (b.single_extension != nullptr)
							if (not (*a.single_extension).is_equivalent(*b.single_extension))
								return false;
							else;
						else
							return false;
					else
						if (b.single_extension == nullptr)
							return false;
					if (a.first_group.size() != b.first_group.size())
						return false;
					for (size_t i = 0; i < a.first_group.size(); ++i)
						if (not a.first_group[i].is_equivalent(b.first_group[i]))
							return false;
					if (a.second_group.size() != b.second_group.size())
						return false;
					for (size_t i = 0; i < a.second_group.size(); ++i)
						if (not a.second_group[i].is_equivalent(b.second_group[i]))
							return false;
					if (a.generic_index != b.generic_index)
						return false;
					return true;
				}

				inline type_info specialize(const std::vector<type_info> types) const {
					return type_info(type_info_enum::specialize, *this, types);
				}

				inline type_info labeled(const std::string lbl) const {
					return type_info(*this, lbl);
				}

				inline bool has_label() const {
					return lbl != "";
				}

				inline std::string label() const {
					return lbl;
				}

				inline bool is_specialization() const {
					return category == type_info_enum::specialize;
				}

				inline type_info specialization_template() const {
					return *single_extension;
				}

				inline std::vector<type_info> specialization_parameters() const {
					return first_group;
				}

				inline bool is_list() const {
					return category == type_info_enum::list;
				}

				inline type_info list_of() const {
					return *single_extension;
				}

				inline bool is_tuple() const {
					return category == type_info_enum::tuple;
				}

				inline std::vector<type_info> tuple_types() const {
					return first_group;
				}

				inline bool is_repeated_tuple() const {
					if (not is_tuple())
						return false;
					if (*this == none)
						return false;
					type_info first;
					bool is_first;
					for (const auto& i : first_group)
						if (is_first) {
							first = i;
							is_first = true;
						}
						else
							if (i != first)
								return false;
					return true;
				}

				inline type_info repeated_tuple_of() const {
					return first_group[0];
				}

				inline size_t repeated_tuple_length() const {
					return first_group.size();
				}

				inline bool is_generic_parameter() const {
					return category == type_info_enum::generic;
				}

				inline size_t generic_parameter_index() const {
					return generic_index;
				}

				inline size_t is_generic() const {
					if (is_generic_parameter())
						return true;
					if (single_extension != nullptr)
						if ((*single_extension).is_generic())
							return true;
					for (const auto& i : first_group)
						if (i.is_generic())
							return true;
					for (const auto& i : second_group)
						if (i.is_generic())
							return true;
					return false;
				}

				inline bool is_function() const {
					return category == type_info_enum::function;
				}

				inline type_info function_return_type() const {
					return *single_extension;
				}

				inline std::vector<type_info> function_arguments() const {
					return first_group;
				}

				inline bool is_code() const {
					return category == type_info_enum::code;
				}

				inline std::vector<type_info> code_inputs() const {
					return first_group;
				}

				inline std::vector<type_info> code_outputs() const {
					return second_group;
				}

				static const type_info boolean;
				static const type_info integer;
				static const type_info number;
				static const type_info any;
				static const type_info string;

				static inline type_info list(const type_info of) {
					return type_info(type_info_enum::list, of);
				}

				static inline type_info tuple(const type_info of, const size_t times) {
					return type_info(type_info_enum::tuple, std::vector<type_info>(times, of));
				}

				static inline type_info tuple(const std::vector<type_info> types) {
					return type_info(type_info_enum::tuple, types);
				}

				static inline type_info generic_parameter(const size_t index) {
					return type_info(index);
				}

				static inline type_info function(const type_info ret, const std::vector<type_info> args) {
					return type_info(type_info_enum::function, ret, args);
				}

				static inline type_info code(const std::vector<type_info> inputs, const std::vector<type_info> outputs) {
					return type_info(type_info_enum::code, inputs, outputs);
				}

				static const type_info none;
				static const type_info position;
				static const type_info position2d;
				static const type_info position3d;
				static const type_info color;
				static const type_info color_without_alpha;
				static const type_info renderable;
				static const type_info sound;

				inline ~type_info() {
					delete single_extension;
				}
			};
		}

		using type_info = implementation::type_info;

		template <typename T>
			struct tuple {
				std::vector<T> data;

				tuple(std::vector<T> d) : data(d) {
				}

				operator std::vector<T>() const {
					return data;
				}

				std::vector<T>* operator->() {
					return &data;
				}

				std::vector<T> operator*() {
					return data;
				}
			};

		using value = boost::make_recursive_variant<
			bool,
			long int,
			double,
			std::vector<boost::recursive_variant_>,
			tuple<boost::recursive_variant_>,
			std::string
		>::type;

		namespace representations {
			using boolean = bool;
			using integer = long int;
			using number = double;
			using list = std::vector<value>;
			using tuple = tuple<value>;
			using string = std::string;
			using function = std::function<value(std::vector<value>)>;
			using code = std::function<std::vector<value>(std::vector<value>)>;
		}

		type_info apply_specialization(const type_info, const std::vector<type_info>);
		std::string to_string(const type_info);
	}
}
#endif
<commit_msg>Formatted types.hh<commit_after>#ifndef	types_h
#define types_h
#include <boost/variant.hpp>
#include <vector>
#include <string>
#include <functional>

namespace doanimate {
	namespace types {
		namespace implementation {
			class type_info;
		}

		implementation::type_info simplify(const implementation::type_info);

		namespace implementation {
			enum type_info_enum {
				boolean,
				integer,
				number,
				list,
				tuple,
				generic,
				function,
				code,
				specialize,
				any,
				string
			};

			class type_info {
				type_info_enum category;
				type_info* single_extension = nullptr;
				std::vector<type_info> first_group = {};
				std::vector<type_info> second_group = {};
				size_t generic_index = 0;
				std::string lbl = "";

				inline type_info(const type_info_enum cat) : category(cat) {
				}

				inline type_info(const type_info_enum cat, type_info ext)
					: category(cat), single_extension(new type_info(ext)) {
				}

				inline type_info(const type_info_enum cat,
						std::vector<type_info> group)
					: category(cat), first_group(group) {
				}

				inline type_info(const type_info_enum cat, type_info ext,
						std::vector<type_info> group)
					: category(cat), single_extension(new type_info(ext)),
					  first_group(group) {
				}

				inline type_info(const type_info_enum cat,
						std::vector<type_info> first,
						std::vector<type_info> second)
					: category(cat), first_group(first), second_group(second) {
				}

				inline type_info(const type_info_enum cat, type_info ext,
						std::vector<type_info> first,
						std::vector<type_info> second)
					: category(cat), single_extension(new type_info(ext)), first_group(first), second_group(second) {
				}

				inline type_info(const size_t index)
					: category(type_info_enum::generic), generic_index(index) {
				}

				inline type_info(const type_info other, const std::string lbl)
					: category(other.category),
					  single_extension(other.single_extension),
					  first_group(other.first_group),
					  second_group(other.second_group),
					  generic_index(other.generic_index), lbl(lbl) {
				}

				public:
				inline type_info() : type_info(type_info_enum::tuple) {
				}

				inline bool operator==(const type_info other) const {
					type_info a = simplify(*this);
					type_info b = simplify(other);
					if (a.category != b.category)
						return false;
					if (a.single_extension != nullptr)
						if (b.single_extension != nullptr)
							if (*a.single_extension != *b.single_extension)
								return false;
							else
								;
						else
							return false;
					else
						if (b.single_extension == nullptr)
							return false;
					if (a.first_group != b.first_group)
						return false;
					if (a.second_group != b.second_group)
						return false;
					if (a.generic_index != b.generic_index)
						return false;
					if (a.lbl != b.lbl)
						return false;
					return true;
				}

				inline bool operator!=(const type_info other) const {
					return not (*this == other);
				}

				inline bool is_equivalent(const type_info other) const {
					type_info a = simplify(*this);
					type_info b = simplify(other);
					if (a.category != b.category)
						return false;
					if (a.single_extension != nullptr)
						if (b.single_extension != nullptr)
							if (not (*a.single_extension).is_equivalent(
										*b.single_extension
									))
								return false;
							else;
						else
							return false;
					else
						if (b.single_extension == nullptr)
							return false;
					if (a.first_group.size() != b.first_group.size())
						return false;
					for (size_t i = 0; i < a.first_group.size(); ++i)
						if (not a.first_group[i].is_equivalent(
									b.first_group[i]
								))
							return false;
					if (a.second_group.size() != b.second_group.size())
						return false;
					for (size_t i = 0; i < a.second_group.size(); ++i)
						if (not a.second_group[i].is_equivalent(
									b.second_group[i]
								))
							return false;
					if (a.generic_index != b.generic_index)
						return false;
					return true;
				}

				inline type_info specialize(const std::vector<type_info> types) const {
					return type_info(type_info_enum::specialize, *this, types);
				}

				inline type_info labeled(const std::string lbl) const {
					return type_info(*this, lbl);
				}

				inline bool has_label() const {
					return lbl != "";
				}

				inline std::string label() const {
					return lbl;
				}

				inline bool is_specialization() const {
					return category == type_info_enum::specialize;
				}

				inline type_info specialization_template() const {
					return *single_extension;
				}

				inline std::vector<type_info> specialization_parameters() const {
					return first_group;
				}

				inline bool is_list() const {
					return category == type_info_enum::list;
				}

				inline type_info list_of() const {
					return *single_extension;
				}

				inline bool is_tuple() const {
					return category == type_info_enum::tuple;
				}

				inline std::vector<type_info> tuple_types() const {
					return first_group;
				}

				inline bool is_repeated_tuple() const {
					if (not is_tuple())
						return false;
					if (*this == none)
						return false;
					type_info first;
					bool is_first;
					for (const auto& i : first_group)
						if (is_first) {
							first = i;
							is_first = true;
						}
						else
							if (i != first)
								return false;
					return true;
				}

				inline type_info repeated_tuple_of() const {
					return first_group[0];
				}

				inline size_t repeated_tuple_length() const {
					return first_group.size();
				}

				inline bool is_generic_parameter() const {
					return category == type_info_enum::generic;
				}

				inline size_t generic_parameter_index() const {
					return generic_index;
				}

				inline size_t is_generic() const {
					if (is_generic_parameter())
						return true;
					if (single_extension != nullptr)
						if ((*single_extension).is_generic())
							return true;
					for (const auto& i : first_group)
						if (i.is_generic())
							return true;
					for (const auto& i : second_group)
						if (i.is_generic())
							return true;
					return false;
				}

				inline bool is_function() const {
					return category == type_info_enum::function;
				}

				inline type_info function_return_type() const {
					return *single_extension;
				}

				inline std::vector<type_info> function_arguments() const {
					return first_group;
				}

				inline bool is_code() const {
					return category == type_info_enum::code;
				}

				inline std::vector<type_info> code_inputs() const {
					return first_group;
				}

				inline std::vector<type_info> code_outputs() const {
					return second_group;
				}

				static const type_info boolean;
				static const type_info integer;
				static const type_info number;
				static const type_info any;
				static const type_info string;

				static inline type_info list(const type_info of) {
					return type_info(type_info_enum::list, of);
				}

				static inline type_info tuple(const type_info of, const size_t times) {
					return type_info(
							type_info_enum::tuple,
							std::vector<type_info>(times, of)
						);
				}

				static inline type_info tuple(const std::vector<type_info> types) {
					return type_info(type_info_enum::tuple, types);
				}

				static inline type_info generic_parameter(const size_t index) {
					return type_info(index);
				}

				static inline type_info function(const type_info ret,
						const std::vector<type_info> args) {
					return type_info(type_info_enum::function, ret, args);
				}

				static inline type_info code(const std::vector<type_info> inputs,
						const std::vector<type_info> outputs) {
					return type_info(type_info_enum::code, inputs, outputs);
				}

				static const type_info none;
				static const type_info position;
				static const type_info position2d;
				static const type_info position3d;
				static const type_info color;
				static const type_info color_without_alpha;
				static const type_info renderable;
				static const type_info sound;

				inline ~type_info() {
					delete single_extension;
				}
			};
		}

		using type_info = implementation::type_info;

		template <typename T>
			struct tuple {
				std::vector<T> data;

				tuple(std::vector<T> d) : data(d) {
				}

				operator std::vector<T>() const {
					return data;
				}

				std::vector<T>* operator->() {
					return &data;
				}

				std::vector<T> operator*() {
					return data;
				}
			};

		using value = boost::make_recursive_variant<
			bool,
			long int,
			double,
			std::vector<boost::recursive_variant_>,
			tuple<boost::recursive_variant_>,
			std::string
				>::type;

		namespace representations {
			using boolean = bool;
			using integer = long int;
			using number = double;
			using list = std::vector<value>;
			using tuple = tuple<value>;
			using string = std::string;
			using function = std::function<value(std::vector<value>)>;
			using code = std::function<std::vector<value>(std::vector<value>)>;
		}

		type_info apply_specialization(const type_info, const std::vector<type_info>);
		std::string to_string(const type_info);
	}
}
#endif
<|endoftext|>


<commit_before>#include <iostream>
using namespace std;

string printSymbol(char s, int n) {
	int i = 0;
	string line = "";

	for (; i < n; i++) {
		line += s;
	}

	return line;
}

int main() {
	int n, i = 1;

	cin >> n;

	for (; i <= n; i++) {
		cout << printSymbol(' ', n - i);
		cout << printSymbol('*', 2 * i - 1);
		cout << "\n";
	}

	return 0;
}
<commit_msg>Exercises.<commit_after>#include <iostream>
using namespace std;

int h;

string printSymbol(char s, int n) {
	int i = 0;
	string line = "";

	for (; i < n; i++) {
		line += s;
	}

	return line;
}

string printSymbol2(char s1, char s2, int n) {
	string line = "";

	cout << printSymbol(s1, n);
	cout << s2;
	cout << printSymbol(s1, h - (2 * n - 1));
	cout << s2;

	return line;
}

int main() {
	int i = 1;

	cin >> h;

	for (; i <= h; i++) {
		cout << printSymbol(' ', h - i);
		cout << printSymbol('*', 2 * i - 1);
		cout << "\n";
	}

	for (i = 1; i <= h; i++) {
		if (i > 1 && i < h) {
			cout << printSymbol2(' ', '*', h - i);
		} else {
			cout << printSymbol(' ', h - i);
			cout << printSymbol('*', 2 * i - 1);
		}

		cout << "\n";
	}

	return 0;
}
<|endoftext|>


<commit_before>#include "drape_frontend/stylist.hpp"

#include "indexer/classificator.hpp"
#include "indexer/feature.hpp"
#include "indexer/feature_visibility.hpp"
#include "indexer/drawing_rules.hpp"
#include "indexer/drules_include.hpp"
#include "indexer/scales.hpp"

#include <algorithm>
#include <limits>

namespace df
{
namespace
{
enum Type
{
  Line      =               1,
  Area      = Line       << 1,
  Symbol    = Area       << 1,
  Caption   = Symbol     << 1,
  Circle    = Caption    << 1,
  PathText  = Circle     << 1,
  Waymarker = PathText   << 1,
  Shield    = Waymarker  << 1,
  CountOfType = PathText + 1
};

inline drule::rule_type_t Convert(Type t)
{
  switch (t)
  {
  case Line     : return drule::line;
  case Area     : return drule::area;
  case Symbol   : return drule::symbol;
  case Caption  : return drule::caption;
  case Circle   : return drule::circle;
  case PathText : return drule::pathtext;
  case Waymarker: return drule::waymarker;
  case Shield   : return drule::shield;
  default:
    return drule::count_of_rules;
  }
}

double constexpr kMinPriority = std::numeric_limits<double>::lowest();

inline bool IsTypeOf(drule::Key const & key, int flags)
{
  int currentFlag = Line;
  while (currentFlag < CountOfType)
  {
    Type type = Type(flags & currentFlag);
    if (type != 0 && key.m_type == Convert(type))
      return true;

    currentFlag <<= 1;
  }

  return false;
}

bool IsMiddleTunnel(int const layer, double const depth)
{
  return layer != feature::LAYER_EMPTY && depth < 19000;
}

class Aggregator
{
public:
  Aggregator(FeatureType & f, feature::EGeomType const type, int const zoomLevel,
             int const keyCount)
    : m_pointStyleFound(false)
    , m_lineStyleFound(false)
    , m_auxCaptionFound(false)
    , m_mainTextType(drule::text_type_name)
    , m_f(f)
    , m_geomType(type)
    , m_zoomLevel(zoomLevel)
  {
    m_rules.reserve(keyCount);
    Init();
  }

  void AggregateKeys(drule::KeysT const & keys)
  {
    for (auto const & key : keys)
      ProcessKey(key);
  }

  void AggregateStyleFlags(drule::KeysT const & keys, bool const nameExists)
  {
    for (auto const & key : keys)
    {
      bool const isNonEmptyCaption = IsTypeOf(key, Caption) && nameExists;
      m_pointStyleFound |= (IsTypeOf(key, Symbol | Circle) || isNonEmptyCaption);
      m_lineStyleFound  |= IsTypeOf(key, Line);
    }
  }

  bool m_pointStyleFound;
  bool m_lineStyleFound;
  bool m_auxCaptionFound;
  drule::text_type_t m_mainTextType;
  buffer_vector<Stylist::TRuleWrapper, 8> m_rules;

private:
  void ProcessKey(drule::Key const & key)
  {
    double depth = key.m_priority;
    if (IsMiddleTunnel(m_depthLayer, depth) && IsTypeOf(key, Line))
    {
      double const layerPart = m_depthLayer * drule::layer_base_priority;
      double const depthPart = fmod(depth, drule::layer_base_priority);
      depth = layerPart + depthPart;
    }

    drule::BaseRule const * const dRule = drule::rules().Find(key);
    if (dRule == nullptr)
      return;

    if (dRule->GetCaption(0) != nullptr)
      m_mainTextType = dRule->GetCaptionTextType(0);

    m_auxCaptionFound |= (dRule->GetCaption(1) != nullptr);

    // Skip lines with zero width.
    if (dRule->GetLine() != nullptr && dRule->GetLine()->width() < 1e-5)
      return;

    m_rules.emplace_back(make_pair(dRule, depth));
  }

  void Init()
  {
    m_depthLayer = m_f.GetLayer();
    if (m_depthLayer == feature::LAYER_TRANSPARENT_TUNNEL)
      m_depthLayer = feature::LAYER_EMPTY;

    if (m_geomType == feature::GEOM_POINT)
      m_priorityModifier = (double)m_f.GetPopulation() / 7E9;
    else
    {
      m2::RectD const r = m_f.GetLimitRect(m_zoomLevel);
      m_priorityModifier = min(1.0, r.SizeX() * r.SizeY() * 10000.0);
    }
  }

  FeatureType & m_f;
  feature::EGeomType m_geomType;
  int const m_zoomLevel;
  double m_priorityModifier;
  int m_depthLayer;
};

uint8_t const CoastlineFlag  = 1;
uint8_t const AreaStyleFlag  = 1 << 1;
uint8_t const LineStyleFlag  = 1 << 2;
uint8_t const PointStyleFlag = 1 << 3;
}  // namespace

IsBuildingHasPartsChecker::IsBuildingHasPartsChecker()
{
  m_types.push_back(classif().GetTypeByPath({"building", "has_parts"}));
}

IsBuildingPartChecker::IsBuildingPartChecker() : BaseChecker(1 /* level */)
{
  m_types.push_back(classif().GetTypeByPath({"building:part"}));
}

IsHatchingTerritoryChecker::IsHatchingTerritoryChecker()
{
  Classificator const & c = classif();
  char const * arr[][2] = {{"leisure", "nature_reserve"},
                           {"boundary", "national_park"},
                           {"landuse", "military"}};
  for (auto const & p : arr)
    m_types.push_back(c.GetTypeByPath({p[0], p[1]}));
}

void CaptionDescription::Init(FeatureType & f, int8_t deviceLang, int const zoomLevel,
                              feature::EGeomType const type, drule::text_type_t const mainTextType,
                              bool const auxCaptionExists)
{
  if (auxCaptionExists || type == feature::GEOM_LINE)
    f.GetPreferredNames(true /* allowTranslit */, deviceLang, m_mainText, m_auxText);
  else
    f.GetReadableName(true /* allowTranslit */, deviceLang, m_mainText);

  // Set max text size to avoid VB/IB overflow in rendering.
  size_t constexpr kMaxTextSize = 200;
  if (m_mainText.size() > kMaxTextSize)
    m_mainText = m_mainText.substr(0, kMaxTextSize) + "...";

  m_roadNumber = f.GetRoadNumber();
  m_houseNumber = f.GetHouseNumber();

  ProcessZoomLevel(zoomLevel);
  ProcessMainTextType(mainTextType);
}

string const & CaptionDescription::GetMainText() const
{
  return m_mainText;
}

string const & CaptionDescription::GetAuxText() const
{
  return m_auxText;
}

string const & CaptionDescription::GetRoadNumber() const
{
  return m_roadNumber;
}

bool CaptionDescription::IsNameExists() const
{
  return !m_mainText.empty() || !m_houseNumber.empty();
}

void CaptionDescription::ProcessZoomLevel(int const zoomLevel)
{
  if (zoomLevel <= scales::GetUpperWorldScale() && !m_auxText.empty())
  {
    m_auxText.clear();
  }

  if (zoomLevel < 5 && m_mainText.size() > 50)
    m_mainText.clear();
}

void CaptionDescription::ProcessMainTextType(drule::text_type_t const & mainTextType)
{
  if (mainTextType == drule::text_type_housenumber)
  {
    m_mainText.swap(m_houseNumber);
    m_houseNumber.clear();
    m_isHouseNumberInMainText = true;
  }
  else if (mainTextType == drule::text_type_name)
  {
    if (!m_houseNumber.empty() &&
        (m_mainText.empty() || m_houseNumber.find(m_mainText) != string::npos))
    {
      m_houseNumber.swap(m_mainText);
      m_isHouseNumberInMainText = true;
    }
  }
}

Stylist::Stylist()
  : m_state(0)
{}

bool Stylist::IsCoastLine() const
{
  return (m_state & CoastlineFlag) != 0;
}

bool Stylist::AreaStyleExists() const
{
  return (m_state & AreaStyleFlag) != 0;
}

bool Stylist::LineStyleExists() const
{
  return (m_state & LineStyleFlag) != 0;
}

bool Stylist::PointStyleExists() const
{
  return (m_state & PointStyleFlag) != 0;
}

CaptionDescription const & Stylist::GetCaptionDescription() const
{
  return m_captionDescriptor;
}

void Stylist::ForEachRule(Stylist::TRuleCallback const & fn) const
{
  typedef rules_t::const_iterator const_iter;
  for (const_iter it = m_rules.begin(); it != m_rules.end(); ++it)
    fn(*it);
}

bool Stylist::IsEmpty() const
{
  return m_rules.empty();
}

void Stylist::RaiseCoastlineFlag()
{
  m_state |= CoastlineFlag;
}

void Stylist::RaiseAreaStyleFlag()
{
  m_state |= AreaStyleFlag;
}

void Stylist::RaiseLineStyleFlag()
{
  m_state |= LineStyleFlag;
}

void Stylist::RaisePointStyleFlag()
{
  m_state |= PointStyleFlag;
}

CaptionDescription & Stylist::GetCaptionDescriptionImpl()
{
  return m_captionDescriptor;
}

bool InitStylist(FeatureType & f, int8_t deviceLang, int const zoomLevel, bool buildings3d, Stylist & s)
{
  feature::TypesHolder const types(f);

  if (!buildings3d && IsBuildingPartChecker::Instance()(types) &&
      !ftypes::IsBuildingChecker::Instance()(types))
    return false;

  drule::KeysT keys;
  auto const geomType = feature::GetDrawRule(types, zoomLevel, keys);

  feature::FilterRulesByRuntimeSelector(f, zoomLevel, keys);

  if (keys.empty())
    return false;

  drule::MakeUnique(keys);

  if (geomType.second)
    s.RaiseCoastlineFlag();

  auto const mainGeomType = feature::EGeomType(geomType.first);

  switch (mainGeomType)
  {
  case feature::GEOM_POINT:
    s.RaisePointStyleFlag();
    break;
  case feature::GEOM_LINE :
    s.RaiseLineStyleFlag();
    break;
  case feature::GEOM_AREA :
    s.RaiseAreaStyleFlag();
    break;
  default:
    ASSERT(false, ());
    return false;
  }

  Aggregator aggregator(f, mainGeomType, zoomLevel, static_cast<int>(keys.size()));
  aggregator.AggregateKeys(keys);

  CaptionDescription & descr = s.GetCaptionDescriptionImpl();
  descr.Init(f, deviceLang, zoomLevel, mainGeomType, aggregator.m_mainTextType, aggregator.m_auxCaptionFound);

  aggregator.AggregateStyleFlags(keys, descr.IsNameExists());

  if (aggregator.m_pointStyleFound)
    s.RaisePointStyleFlag();
  if (aggregator.m_lineStyleFound)
    s.RaiseLineStyleFlag();

  s.m_rules.swap(aggregator.m_rules);

  return true;
}

double GetFeaturePriority(FeatureType & f, int const zoomLevel)
{
  drule::KeysT keys;
  pair<int, bool> const geomType = feature::GetDrawRule(feature::TypesHolder(f), zoomLevel, keys);

  feature::FilterRulesByRuntimeSelector(f, zoomLevel, keys);

  auto const mainGeomType = feature::EGeomType(geomType.first);

  Aggregator aggregator(f, mainGeomType, zoomLevel, static_cast<int>(keys.size()));
  aggregator.AggregateKeys(keys);

  double maxPriority = kMinPriority;
  for (auto const & rule : aggregator.m_rules)
  {
    if (rule.second > maxPriority)
      maxPriority = rule.second;
  }

  return maxPriority;
}
}  // namespace df
<commit_msg>Fixed arrows along oneway roads<commit_after>#include "drape_frontend/stylist.hpp"

#include "indexer/classificator.hpp"
#include "indexer/feature.hpp"
#include "indexer/feature_visibility.hpp"
#include "indexer/drawing_rules.hpp"
#include "indexer/drules_include.hpp"
#include "indexer/scales.hpp"

#include <algorithm>
#include <limits>

namespace df
{
namespace
{
enum Type
{
  Line      =               1,
  Area      = Line       << 1,
  Symbol    = Area       << 1,
  Caption   = Symbol     << 1,
  Circle    = Caption    << 1,
  PathText  = Circle     << 1,
  Waymarker = PathText   << 1,
  Shield    = Waymarker  << 1,
  CountOfType = PathText + 1
};

inline drule::rule_type_t Convert(Type t)
{
  switch (t)
  {
  case Line     : return drule::line;
  case Area     : return drule::area;
  case Symbol   : return drule::symbol;
  case Caption  : return drule::caption;
  case Circle   : return drule::circle;
  case PathText : return drule::pathtext;
  case Waymarker: return drule::waymarker;
  case Shield   : return drule::shield;
  default:
    return drule::count_of_rules;
  }
}

double constexpr kMinPriority = std::numeric_limits<double>::lowest();

inline bool IsTypeOf(drule::Key const & key, int flags)
{
  int currentFlag = Line;
  while (currentFlag < CountOfType)
  {
    Type type = Type(flags & currentFlag);
    if (type != 0 && key.m_type == Convert(type))
      return true;

    currentFlag <<= 1;
  }

  return false;
}

bool IsMiddleTunnel(int const layer, double const depth)
{
  return layer != feature::LAYER_EMPTY && depth < 19000;
}

class Aggregator
{
public:
  Aggregator(FeatureType & f, feature::EGeomType const type, int const zoomLevel,
             int const keyCount)
    : m_pointStyleFound(false)
    , m_lineStyleFound(false)
    , m_auxCaptionFound(false)
    , m_mainTextType(drule::text_type_name)
    , m_f(f)
    , m_geomType(type)
    , m_zoomLevel(zoomLevel)
  {
    m_rules.reserve(keyCount);
    Init();
  }

  void AggregateKeys(drule::KeysT const & keys)
  {
    for (auto const & key : keys)
      ProcessKey(key);
  }

  void AggregateStyleFlags(drule::KeysT const & keys, bool const nameExists)
  {
    for (auto const & key : keys)
    {
      bool const isNonEmptyCaption = IsTypeOf(key, Caption) && nameExists;
      m_pointStyleFound |= (IsTypeOf(key, Symbol | Circle) || isNonEmptyCaption);
      m_lineStyleFound  |= IsTypeOf(key, Line);
    }
  }

  bool m_pointStyleFound;
  bool m_lineStyleFound;
  bool m_auxCaptionFound;
  drule::text_type_t m_mainTextType;
  buffer_vector<Stylist::TRuleWrapper, 8> m_rules;

private:
  void ProcessKey(drule::Key const & key)
  {
    double depth = key.m_priority;
    if (IsMiddleTunnel(m_depthLayer, depth) && IsTypeOf(key, Line))
    {
      double const layerPart = m_depthLayer * drule::layer_base_priority;
      double const depthPart = fmod(depth, drule::layer_base_priority);
      depth = layerPart + depthPart;
    }

    drule::BaseRule const * const dRule = drule::rules().Find(key);
    if (dRule == nullptr)
      return;

    if (dRule->GetCaption(0) != nullptr)
      m_mainTextType = dRule->GetCaptionTextType(0);

    m_auxCaptionFound |= (dRule->GetCaption(1) != nullptr);

    // Skip lines with zero width. Lines can have zero width only if they have
    // path symbols along.
    auto const lineRule = dRule->GetLine();
    if (lineRule != nullptr && (lineRule->width() < 1e-5 && !lineRule->has_pathsym()))
      return;

    m_rules.emplace_back(make_pair(dRule, depth));
  }

  void Init()
  {
    m_depthLayer = m_f.GetLayer();
    if (m_depthLayer == feature::LAYER_TRANSPARENT_TUNNEL)
      m_depthLayer = feature::LAYER_EMPTY;

    if (m_geomType == feature::GEOM_POINT)
      m_priorityModifier = (double)m_f.GetPopulation() / 7E9;
    else
    {
      m2::RectD const r = m_f.GetLimitRect(m_zoomLevel);
      m_priorityModifier = min(1.0, r.SizeX() * r.SizeY() * 10000.0);
    }
  }

  FeatureType & m_f;
  feature::EGeomType m_geomType;
  int const m_zoomLevel;
  double m_priorityModifier;
  int m_depthLayer;
};

uint8_t const CoastlineFlag  = 1;
uint8_t const AreaStyleFlag  = 1 << 1;
uint8_t const LineStyleFlag  = 1 << 2;
uint8_t const PointStyleFlag = 1 << 3;
}  // namespace

IsBuildingHasPartsChecker::IsBuildingHasPartsChecker()
{
  m_types.push_back(classif().GetTypeByPath({"building", "has_parts"}));
}

IsBuildingPartChecker::IsBuildingPartChecker() : BaseChecker(1 /* level */)
{
  m_types.push_back(classif().GetTypeByPath({"building:part"}));
}

IsHatchingTerritoryChecker::IsHatchingTerritoryChecker()
{
  Classificator const & c = classif();
  char const * arr[][2] = {{"leisure", "nature_reserve"},
                           {"boundary", "national_park"},
                           {"landuse", "military"}};
  for (auto const & p : arr)
    m_types.push_back(c.GetTypeByPath({p[0], p[1]}));
}

void CaptionDescription::Init(FeatureType & f, int8_t deviceLang, int const zoomLevel,
                              feature::EGeomType const type, drule::text_type_t const mainTextType,
                              bool const auxCaptionExists)
{
  if (auxCaptionExists || type == feature::GEOM_LINE)
    f.GetPreferredNames(true /* allowTranslit */, deviceLang, m_mainText, m_auxText);
  else
    f.GetReadableName(true /* allowTranslit */, deviceLang, m_mainText);

  // Set max text size to avoid VB/IB overflow in rendering.
  size_t constexpr kMaxTextSize = 200;
  if (m_mainText.size() > kMaxTextSize)
    m_mainText = m_mainText.substr(0, kMaxTextSize) + "...";

  m_roadNumber = f.GetRoadNumber();
  m_houseNumber = f.GetHouseNumber();

  ProcessZoomLevel(zoomLevel);
  ProcessMainTextType(mainTextType);
}

string const & CaptionDescription::GetMainText() const
{
  return m_mainText;
}

string const & CaptionDescription::GetAuxText() const
{
  return m_auxText;
}

string const & CaptionDescription::GetRoadNumber() const
{
  return m_roadNumber;
}

bool CaptionDescription::IsNameExists() const
{
  return !m_mainText.empty() || !m_houseNumber.empty();
}

void CaptionDescription::ProcessZoomLevel(int const zoomLevel)
{
  if (zoomLevel <= scales::GetUpperWorldScale() && !m_auxText.empty())
  {
    m_auxText.clear();
  }

  if (zoomLevel < 5 && m_mainText.size() > 50)
    m_mainText.clear();
}

void CaptionDescription::ProcessMainTextType(drule::text_type_t const & mainTextType)
{
  if (mainTextType == drule::text_type_housenumber)
  {
    m_mainText.swap(m_houseNumber);
    m_houseNumber.clear();
    m_isHouseNumberInMainText = true;
  }
  else if (mainTextType == drule::text_type_name)
  {
    if (!m_houseNumber.empty() &&
        (m_mainText.empty() || m_houseNumber.find(m_mainText) != string::npos))
    {
      m_houseNumber.swap(m_mainText);
      m_isHouseNumberInMainText = true;
    }
  }
}

Stylist::Stylist()
  : m_state(0)
{}

bool Stylist::IsCoastLine() const
{
  return (m_state & CoastlineFlag) != 0;
}

bool Stylist::AreaStyleExists() const
{
  return (m_state & AreaStyleFlag) != 0;
}

bool Stylist::LineStyleExists() const
{
  return (m_state & LineStyleFlag) != 0;
}

bool Stylist::PointStyleExists() const
{
  return (m_state & PointStyleFlag) != 0;
}

CaptionDescription const & Stylist::GetCaptionDescription() const
{
  return m_captionDescriptor;
}

void Stylist::ForEachRule(Stylist::TRuleCallback const & fn) const
{
  typedef rules_t::const_iterator const_iter;
  for (const_iter it = m_rules.begin(); it != m_rules.end(); ++it)
    fn(*it);
}

bool Stylist::IsEmpty() const
{
  return m_rules.empty();
}

void Stylist::RaiseCoastlineFlag()
{
  m_state |= CoastlineFlag;
}

void Stylist::RaiseAreaStyleFlag()
{
  m_state |= AreaStyleFlag;
}

void Stylist::RaiseLineStyleFlag()
{
  m_state |= LineStyleFlag;
}

void Stylist::RaisePointStyleFlag()
{
  m_state |= PointStyleFlag;
}

CaptionDescription & Stylist::GetCaptionDescriptionImpl()
{
  return m_captionDescriptor;
}

bool InitStylist(FeatureType & f, int8_t deviceLang, int const zoomLevel, bool buildings3d, Stylist & s)
{
  feature::TypesHolder const types(f);

  if (!buildings3d && IsBuildingPartChecker::Instance()(types) &&
      !ftypes::IsBuildingChecker::Instance()(types))
    return false;

  drule::KeysT keys;
  auto const geomType = feature::GetDrawRule(types, zoomLevel, keys);

  feature::FilterRulesByRuntimeSelector(f, zoomLevel, keys);

  if (keys.empty())
    return false;

  drule::MakeUnique(keys);

  if (geomType.second)
    s.RaiseCoastlineFlag();

  auto const mainGeomType = feature::EGeomType(geomType.first);

  switch (mainGeomType)
  {
  case feature::GEOM_POINT:
    s.RaisePointStyleFlag();
    break;
  case feature::GEOM_LINE :
    s.RaiseLineStyleFlag();
    break;
  case feature::GEOM_AREA :
    s.RaiseAreaStyleFlag();
    break;
  default:
    ASSERT(false, ());
    return false;
  }

  Aggregator aggregator(f, mainGeomType, zoomLevel, static_cast<int>(keys.size()));
  aggregator.AggregateKeys(keys);

  CaptionDescription & descr = s.GetCaptionDescriptionImpl();
  descr.Init(f, deviceLang, zoomLevel, mainGeomType, aggregator.m_mainTextType, aggregator.m_auxCaptionFound);

  aggregator.AggregateStyleFlags(keys, descr.IsNameExists());

  if (aggregator.m_pointStyleFound)
    s.RaisePointStyleFlag();
  if (aggregator.m_lineStyleFound)
    s.RaiseLineStyleFlag();

  s.m_rules.swap(aggregator.m_rules);

  return true;
}

double GetFeaturePriority(FeatureType & f, int const zoomLevel)
{
  drule::KeysT keys;
  pair<int, bool> const geomType = feature::GetDrawRule(feature::TypesHolder(f), zoomLevel, keys);

  feature::FilterRulesByRuntimeSelector(f, zoomLevel, keys);

  auto const mainGeomType = feature::EGeomType(geomType.first);

  Aggregator aggregator(f, mainGeomType, zoomLevel, static_cast<int>(keys.size()));
  aggregator.AggregateKeys(keys);

  double maxPriority = kMinPriority;
  for (auto const & rule : aggregator.m_rules)
  {
    if (rule.second > maxPriority)
      maxPriority = rule.second;
  }

  return maxPriority;
}
}  // namespace df
<|endoftext|>


<commit_before>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_OPERATORS_BASE_HH
#define DUNE_GDT_OPERATORS_BASE_HH

#include <dune/gdt/assembler/system.hh>
#include <dune/gdt/assembler/local/codim0.hh>

#include "interfaces.hh"

namespace Dune {
namespace GDT {
namespace Operators {

template< class Traits >
class AssemblableVolumeBase
    : public AssemblableOperatorInterface< Traits >
    , public Functor::Codim0< typename Traits::GridViewType >
{
  typedef AssemblableOperatorInterface< Traits > InterfaceType;
public:
  typedef typename Traits::GridViewType     GridViewType;
  typedef typename Traits::SourceSpaceType  SourceSpaceType;
  typedef typename Traits::RangeSpaceType   RangeSpaceType;
  typedef typename Traits::MatrixType       MatrixType;

  typedef typename MatrixType::ScalarType   FieldType;
private:
  typedef TmpStorageProvider::Matrices< FieldType >         TmpMatricesProviderType;
  typedef typename Traits::LocalOperatorType                LocalOperatorType;
  typedef LocalAssembler::Codim0Matrix< LocalOperatorType > LocalAssemblerType;
  typedef Stuff::LA::Solver< MatrixType >                   LinearSolverType;

public:
  using typename InterfaceType::EntityType;

  AssemblableVolumeBase(MatrixType& matrix,
                        const SourceSpaceType& source_space,
                        const RangeSpaceType& range_space,
                        const GridViewType& grid_view)
    : matrix_(matrix)
    , source_space_(source_space)
    , range_space_(range_space)
    , grid_view_(grid_view)
    , local_assembler_(nullptr)
    , tmp_storage_(nullptr)
    , linear_solver_(nullptr)
    , prepared_(false)
    , assembled_(false)
  {}

  AssemblableVolumeBase(MatrixType& matrix,
                        const SourceSpaceType& source_space,
                        const RangeSpaceType& range_space)
    : matrix_(matrix)
    , source_space_(source_space)
    , range_space_(range_space)
    , grid_view_(*(source_space_.grid_view()))
    , local_assembler_(nullptr)
    , tmp_storage_(nullptr)
    , linear_solver_(nullptr)
    , prepared_(false)
    , assembled_(false)
  {}

  AssemblableVolumeBase(MatrixType& matrix,
                        const SourceSpaceType& source_space)
    : matrix_(matrix)
    , source_space_(source_space)
    , range_space_(source_space_)
    , grid_view_(*(source_space_.grid_view()))
    , local_assembler_(nullptr)
    , tmp_storage_(nullptr)
    , linear_solver_(nullptr)
    , prepared_(false)
    , assembled_(false)
  {}

  const GridViewType& grid_view() const
  {
    return grid_view_;
  }

  const RangeSpaceType& range_space() const
  {
    return range_space_;
  }

  const SourceSpaceType& source_space() const
  {
    return source_space_;
  }

  MatrixType& matrix()
  {
    return matrix_;
  }

  const MatrixType& matrix() const
  {
    return matrix_;
  }

private:
  virtual const LocalOperatorType& local_operator() const = 0;

public:
  virtual void prepare()
  {
    if (!assembled_ && !prepared_) {
      local_assembler_ = std::unique_ptr< LocalAssemblerType >(new LocalAssemblerType(local_operator()));
      tmp_storage_
          = std::unique_ptr< TmpMatricesProviderType >(new TmpMatricesProviderType(local_assembler_->numTmpObjectsRequired(),
                                                                                range_space_.mapper().maxNumDofs(),
                                                                                source_space_.mapper().maxNumDofs()));
      prepared_ = true;
    }
  } // ... prepare()

  virtual void apply_local(const EntityType& entity)
  {
    assert(prepared_);
    assert(local_assembler_);
    assert(tmp_storage_);
    local_assembler_->assembleLocal(range_space_, source_space_,
                                    entity,
                                    matrix(),
                                    tmp_storage_->matrices(), tmp_storage_->indices());
  } // ... apply_local(...)

  virtual void finalize()
  {
    if (!linear_solver_)
      linear_solver_ = std::unique_ptr< LinearSolverType >(new LinearSolverType(matrix_));
  }

  void assemble()
  {
    if (!assembled_) {
      GridWalker< GridViewType > grid_walker(grid_view_);
      grid_walker.add(*this);
      grid_walker.walk();
      assembled_ = true;
    }
  } // ... assemble()

  template< class S, class R >
  void apply(const Stuff::LA::VectorInterface< S >& source, Stuff::LA::VectorInterface< R >& range)
  {
    typedef typename S::derived_type SourceType;
    typedef typename R::derived_type RangeType;
    assemble();
    matrix_.mv(static_cast< const SourceType& >(source), static_cast< RangeType& >(range));
  }

  static std::vector< std::string > invert_options()
  {
    return LinearSolverType::options();
  }

  static Stuff::Common::ConfigTree invert_options(const std::string& type)
  {
    return LinearSolverType::options(type);
  }

  template< class R, class S >
  void apply_inverse(const Stuff::LA::VectorInterface< R >& range,
                     Stuff::LA::VectorInterface< S >& source,
                     const Stuff::Common::ConfigTree& opts)
  {
    typedef typename S::derived_type SourceType;
    typedef typename R::derived_type RangeType;
    assemble();
    assert(linear_solver_);
    linear_solver_->apply(static_cast< const RangeType& >(range), static_cast< SourceType& >(source), opts);
  }

private:
  MatrixType& matrix_;
  const SourceSpaceType& source_space_;
  const RangeSpaceType& range_space_;
  const GridViewType& grid_view_;
  std::unique_ptr< LocalAssemblerType > local_assembler_;
  std::unique_ptr< TmpMatricesProviderType > tmp_storage_;
  std::unique_ptr< LinearSolverType > linear_solver_;
  bool prepared_;
  bool assembled_;
}; // class AssemblableVolumeBase

} // namespace Operators
} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_OPERATORS_BASE_HH
<commit_msg>[operators.base] replaced AssemblableVolumeBase by MatrixBasedBase<commit_after>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_OPERATORS_BASE_HH
#define DUNE_GDT_OPERATORS_BASE_HH

#include <dune/gdt/assembler/system.hh>
#include <dune/gdt/assembler/local/codim0.hh>

#include "interfaces.hh"

namespace Dune {
namespace GDT {
namespace Operators {

template< class Traits >
class MatrixBasedBase
  : public AssemblableOperatorInterface< Traits >
{
  typedef AssemblableOperatorInterface< Traits > InterfaceType;
public:
  typedef typename Traits::GridViewType     GridViewType;
  typedef typename Traits::SourceSpaceType  SourceSpaceType;
  typedef typename Traits::RangeSpaceType   RangeSpaceType;
  typedef typename Traits::MatrixType       MatrixType;

  typedef typename MatrixType::ScalarType   FieldType;
private:
  typedef Stuff::LA::Solver< MatrixType > LinearSolverType;

public:
  using typename InterfaceType::EntityType;

  MatrixBasedBase(MatrixType& matrix,
                  const SourceSpaceType& source_space,
                  const RangeSpaceType& range_space,
                  const GridViewType& grid_view)
    : matrix_(matrix)
    , source_space_(source_space)
    , range_space_(range_space)
    , grid_view_(grid_view)
    , assembled_(false)
  {}

  MatrixBasedBase(MatrixType& matrix, const SourceSpaceType& source_space, const RangeSpaceType& range_space)
    : matrix_(matrix)
    , source_space_(source_space)
    , range_space_(range_space)
    , grid_view_(*(source_space_.grid_view()))
    , assembled_(false)
  {}

  MatrixBasedBase(MatrixType& matrix, const SourceSpaceType& source_space)
    : matrix_(matrix)
    , source_space_(source_space)
    , range_space_(source_space_)
    , grid_view_(*(source_space_.grid_view()))
    , assembled_(false)
  {}

  const GridViewType& grid_view() const
  {
    return grid_view_;
  }

  const RangeSpaceType& range_space() const
  {
    return range_space_;
  }

  const SourceSpaceType& source_space() const
  {
    return source_space_;
  }

  MatrixType& matrix()
  {
    return matrix_;
  }

  const MatrixType& matrix() const
  {
    return matrix_;
  }

  virtual void assemble() = 0;

  template< class S, class R >
  void apply(const Stuff::LA::VectorInterface< S >& source, Stuff::LA::VectorInterface< R >& range)
  {
    assemble();
    matrix_.mv(source.as_imp(), range.as_imp());
  } // ... apply(...)

  static std::vector< std::string > invert_options()
  {
    return LinearSolverType::options();
  }

  static Stuff::Common::ConfigTree invert_options(const std::string& type)
  {
    return LinearSolverType::options(type);
  }

  template< class R, class S >
  void apply_inverse(const Stuff::LA::VectorInterface< R >& range,
                     Stuff::LA::VectorInterface< S >& source,
                     const Stuff::Common::ConfigTree& opts)
  {
    assemble();
    LinearSolverType(matrix).apply(range.as_imp(), source.as_imp(), opts);
  } // ... apply_inverse(...)

private:
  MatrixType& matrix_;
  const SourceSpaceType& source_space_;
  const RangeSpaceType& range_space_;
  const GridViewType& grid_view_;
  bool assembled_;
}; // class MatrixBasedBase

} // namespace Operators
} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_OPERATORS_BASE_HH
<|endoftext|>


<commit_before>//
//  emulator_main.c
//  dcpu
//
//  Created by Artur on 30/09/2013.
//  Copyright (c) 2013 Artur Mazurek. All rights reserved.
//

#include <cstdint>
#include <cstdlib>

#include <fstream>
#include <iostream>
#include <stdexcept>
#include <vector>

#include "Core.h"

using namespace std;

enum ReturnCodes {
    RETURN_SUCCESS = 0,
    RETURN_PROGRAM_ERROR = 1,
    RETURN_WRONG_INVOCATION = 2,
    RETURN_FILE_ERROR = 3,
    RETURN_CORE_EXCEPTION = 4,
};

static constexpr int BUF_SIZE = 1024;

void mainLoop(Core& core);
void printHelp();
void printMainLoopHelp();

int main(int argc, char** argv) {
    if(argc < 2) {
        printHelp();
        return RETURN_WRONG_INVOCATION;
    }

    ifstream inputFile{argv[1], ios_base::in | ios_base::binary | ios::ate};
    if(inputFile.bad()) {
        cout << "Could not open " << argv[1] << endl;
        return RETURN_FILE_ERROR;
    }

    auto size = inputFile.tellg();
    std::vector<uint16_t> memory(size / sizeof(uint16_t));
    inputFile.seekg(0, ios::beg);
    inputFile.read(reinterpret_cast<char*>(memory.data()), size);
    inputFile.close();

    Core core;
    core.resetState();
    core.setMemory(memory);

    try {
        mainLoop(core);
    } catch(const std::runtime_error& e) {
        cout << "Execution error - " << e.what() << endl;
        return RETURN_PROGRAM_ERROR;
    }

    return RETURN_SUCCESS;
}

void printHelp() {
    cout << "dcpu-emu - an emulator of DCPU-16\n";
    cout << "    dcpu-emu <binary_path>" << endl;
}

void printMainLoopHelp() {
    cout << "Help unavailable yet." << endl;
}

void mainLoop(Core& core) {
    cout << "DCPU-16 running:" << endl;

    string in;
    while(true) {
        cin >> in;

        if(in == "q" || in == "quit") {
            cout << "Goodbye" << endl;
            break;
        } else if(in == "c" || in == "cycle") {
            core.cycle();
        } else if(in == "pr" || in == "print registers") {
            core.printRegisters();
        } else if(in == "h" || in == "help") {
            printMainLoopHelp();
        } else {
            cout << "Use 'h' or 'help' for help on commands, 'q' or 'quit' to quit" << endl;
        }
    }
}
<commit_msg>Core now has option to print out memory<commit_after>//
//  emulator_main.c
//  dcpu
//
//  Created by Artur on 30/09/2013.
//  Copyright (c) 2013 Artur Mazurek. All rights reserved.
//

#include <cstdint>
#include <cstdlib>

#include <fstream>
#include <iostream>
#include <limits>
#include <sstream>
#include <stdexcept>
#include <vector>

#include "Core.h"

using namespace std;

enum ReturnCodes {
    RETURN_SUCCESS = 0,
    RETURN_PROGRAM_ERROR = 1,
    RETURN_WRONG_INVOCATION = 2,
    RETURN_FILE_ERROR = 3,
    RETURN_CORE_EXCEPTION = 4,
};

static constexpr int BUF_SIZE = 1024;

void mainLoop(Core& core);
void printHelp();
void printMainLoopHelp();

int main(int argc, char** argv) {
    if(argc < 2) {
        printHelp();
        return RETURN_WRONG_INVOCATION;
    }

    ifstream inputFile{argv[1], ios_base::in | ios_base::binary | ios::ate};
    if(inputFile.bad()) {
        cout << "Could not open " << argv[1] << endl;
        return RETURN_FILE_ERROR;
    }

    auto size = inputFile.tellg();
    std::vector<uint16_t> memory(size / sizeof(uint16_t));
    inputFile.seekg(0, ios::beg);
    inputFile.read(reinterpret_cast<char*>(memory.data()), size);
    inputFile.close();

    Core core;
    core.resetState();
    core.setMemory(memory);

    try {
        mainLoop(core);
    } catch(const std::runtime_error& e) {
        cout << "Execution error - " << e.what() << endl;
        return RETURN_PROGRAM_ERROR;
    }

    return RETURN_SUCCESS;
}

void printHelp() {
    cout << "dcpu-emu - an emulator of DCPU-16\n";
    cout << "    dcpu-emu <binary_path>" << endl;
}

void printMainLoopHelp() {
    cout << "Help unavailable yet." << endl;
}

void mainLoop(Core& core) {
    cout << "DCPU-16 running:" << endl;

    string in;
    while(true) {
        getline(cin, in);

        if(in == "q" || in == "quit") {
            cout << "Goodbye" << endl;
            break;
        } else if(in == "c" || in == "cycle") {
            core.cycle();
        } else if(in == "pr" || in == "print registers") {
            core.printRegisters();
        } else if(in == "h" || in == "help") {
            printMainLoopHelp();
        } else if(in.find("pm") == 0 || in.find("print memory") == 0) {
            cout << "Enter index and length" << endl;

            string s;
            getline(cin, s);
            stringstream ss{s};

            uint16_t begin = 0, len = 0;
            if(!(ss >> begin) || !(ss >> len)) {
                cout << "Wrong line encountered - " << s << endl;
                continue;
            }
            core.printMemory(begin, begin + len);
        } else {
            if(in.size()) {
                cout << "Use 'h' or 'help' for help on commands, 'q' or 'quit' to quit" << endl;
            }
        }
    }
}
<|endoftext|>


<commit_before>#pragma once

#include <limits>
#include <vector>
#include <string>
#include <fstream>
#include <sstream>
#include <type_traits>

namespace DataLoader
{
	enum class Kind
	{
		Arbitrary,
		Vector,
		Matrix
	};

	namespace Flags
	{
		// No Flags
		const unsigned NullOpts = 0;

		namespace Vector
		{
			namespace Parse
			{
				// Read vector's size first (automatically check for items count)
				const unsigned Size = 1;

				// Read vector's elements line by line
				const unsigned ItemsLineByLine = (1 << 1);

				// Read vector's elements at one as a delimeter-separated string
				const unsigned ItemsAtOnce = (1 << 2);
			}

			namespace Check
			{
				// All loaded vectors should have the same length
				const unsigned LengthEquality = (1 << 3);
			}
		}

		namespace Matrix
		{
			/*
				-- Work with only 2D matrix
				-- Matrix should always has dimentions being put before the data
				-- The number of rows and columns are checked after full read
			*/

			namespace Parse
			{
				// Read dimentions: each value on separate line {val_1 \n val_2}
				const unsigned DimentionsLineByLine = 1;

				// Read dimentions: each value on the same line {val_1 <delim> val_2 }
				const unsigned DimentionsAtOnce = (1 << 1);
			}

			namespace Check {}
		}
	}

	// Namespace Aliases
	namespace Flags_Vector_Parse = Flags::Vector::Parse;
	namespace Flags_Vector_Check = Flags::Vector::Check;
	namespace Flags_Matrix_Parse = Flags::Matrix::Parse;
	namespace Flags_Matrix_Check = Flags::Matrix::Check;

	namespace Flags
	{
		// [ReadVector]

		/* Assume that size for vector is not provided */
		//const unsigned VectorNoSize = 1;
		/* Read size of vector and validate if the number of given items corresponds */
		//const unsigned VectorReadSize = (1 << 1);
		/* Check if all vectors have the same length */
		//const unsigned CheckVectorsLenEquality = (1 << 2);

		// [ReadMatrix]

		/* Read dimensions (row, col) */
		//const unsigned ReadDimentions = (1 << 3);
		/* Read dimentions: each value on separate line {val_1 \n val_2} */
		//const unsigned ReadDimLineByLine = (1 << 4);
		/* Read dimentions: each value on the same line {val_1 <delim> val_2 } */
		//const unsigned ReadDimOneLine = (1 << 5);

		// [ReadArbitrary]

		/* If met delimeter separated values, read one by one */
		const unsigned ReadSeparately = (1 << 6);
		/* If met delimeter separated values, read as vector */
		const unsigned ReadContinuously = (1 << 7);
	}

	namespace State
	{
		const unsigned Idle = 1; // ok
		const unsigned FileAccessError = (1 << 1); // bad
		const unsigned FileReadFormatError = (1 << 2); // fail
		const unsigned FileReadFailure = (1 << 3); // bad/ios::bad
		const unsigned VectorItemsWrongNumber = (1 << 4); // fail
		const unsigned VectorsHaveDifferentLength = (1 << 4); // fail
		const unsigned WrongReadConfiguration = (1 << 5); // fail
		const unsigned VectorInvalidIndex = (1 << 5); // bad
	}

	// Restricting the usage of Loader class
	template<class U>
	struct EnableForArithmeticType {
		typedef typename std::enable_if<std::is_arithmetic<U>::value>::type type;
	};

	template<typename U, typename Enable = EnableForArithmeticType<U>::type>
	class Loader
	{
	private:

		// Name of the input data file
		std::string _file;

		// Default delimeter
		char _delimeter{ ',' };

		// Reader state
		unsigned _state{ State::Idle };

		// Service variables
		size_t sizeRow{ 0 }, sizeCol{ 0 };

		// Storage for read data
		std::vector<std::vector<U>> _storageVector;
		std::vector<U> _storageMatrix;

		void split(std::fstream& stream, std::vector<U>& storage, size_t lines_to_read)
		{
			std::string line;
			std::stringstream sstream;
			std::stringstream sconvert;
			std::string item;
			U num;

			while (!stream.eof() && lines_to_read--)
			{
				// Read vector's items
				std::getline(stream, line);

				if (!stream.eof() && stream.rdstate() != std::ios::goodbit)
				{
					if (stream.fail()) _state = State::FileReadFormatError;
					if (stream.bad()) _state = State::FileReadFailure;
					break;
				}

				sstream.str(line);
				while (std::getline(sstream, item, _delimeter)) {
					sconvert.str(item);
					sconvert >> num;
					sconvert.clear();
					storage.push_back(num);
				}

				sstream.clear();
			}
		}

	public:

		explicit Loader(std::string file) : _file(file) {};

		// Settings: change delimeter character (',' by default)
		inline void delimeter(char delimeter) { _delimeter = delimeter; }

		// Service: get current state
		inline unsigned state() const { return _state; }

		// Service: state check aliases
		inline bool is_ok() const { return _state == State::Idle; };
		inline bool is_bad() const {
			return
				_state == State::FileAccessError ||
				_state == State::FileReadFailure ||
				_state == State::VectorInvalidIndex;
		};
		inline bool is_fail() const { return !is_ok() && !is_bad(); };

		// Service: reset internal state
		void refresh()
		{
			_state = State::Idle;
			_storageVector.clear();
		}

		// Service: get vector length
		size_t arg_vector_len(size_t idx)
		{
			if (idx >= _storageVector.size())
			{
				_state = State::VectorInvalidIndex;
				return std::numeric_limits<size_t>::max();
			}

			return _storageVector[idx].size();
		}

		// Return i-th vector
		std::vector<U> arg_vector(size_t idx)
		{
			if (idx >= _storageVector.size())
				return std::vector<U>{};

			return _storageVector[idx];
		};

		// Fill in given vector storage
		void arg_vector(size_t idx, std::vector<U>& storage)
		{
			if (idx >= _storageVector.size())
				return;

			storage.clear();
			storage.reserve(_storageVector[idx].size());
			std::copy(_storageVector[idx].begin(), _storageVector[idx].end(), std::back_inserter(storage));
		};

		// Fill in given array storage
		void arg_vector(size_t idx, U* storage)
		{
			if (!storage || idx >= _storageVector.size())
				return;

			for (auto v : _storageVector[idx])
				*storage++ = U(v);
		}

		// Return flattened matrix
		std::vector<U> arg_matrix()
		{
			return _storageMatrix();
		}

		// Fill in given array storage
		void arg_matrix(U* storage)
		{
			if (!storage)
				return;

			for (auto v : _storageMatrix)
				*storage++ = U(v);
		}

		void arg_matrix_dims(int& row, int& col)
		{
			row = sizeRow;
			col = sizeCol;
		}

		// Parse input file without data specification
		void read_arbitrary(unsigned opts = Flags::ReadSeparately, Kind type = Kind::Arbitrary)
		{}

		// Parse input file for vector-based data
		void read_vector(unsigned check_opts = Flags::NullOpts,
			unsigned parse_opts = Flags_Vector_Parse::ItemsAtOnce, Kind type = Kind::Vector)
		{
			size_t lenNextVector{ 0 }, lenAllVectors{ 0 };
			std::string line, line1, line2;
			std::fstream fstream;
			std::istringstream sstream;

			fstream.open(_file, std::ios_base::in);

			if (!fstream.is_open())
			{
				_state = State::FileAccessError;
				return;
			}

			_storageVector.clear();

			// Validate vector length if appropriate option is given
			bool checkVecLength = parse_opts & Flags_Vector_Parse::Size;
			// For each vector given check if items number remains the same
			bool checkVecEquality = check_opts & Flags_Vector_Check::LengthEquality;
			// If no Size is given and parse option is set to ItemsLineByLine,
			// we are to read in one vector storage until the end of the file
			bool readUntilEOF = !checkVecLength && (parse_opts & Flags_Vector_Parse::ItemsLineByLine);

			while (std::getline(fstream, line))
			{
				std::vector<U> storageItem;

				// Read vector's length
				if (checkVecLength)
				{
					sstream.str(line);
					sstream >> lenNextVector;
					sstream.clear();

					storageItem.reserve(lenNextVector);
				}

				size_t line_to_read = { 0 };
				// How many lines we need to read for a vector to be filled?
				//  -- if "ReadUntilEOF" flag is set, read until the EOF (lines to read = MAX(size_t))
				//  -- if "ItemsAtOnce" flag is set, read one line no matter if we are given size or not
				//  -- last case: flag "ItemsLineByLine" is set and "Size" flag is given, read "LenNextVector" lines
				line_to_read =
					readUntilEOF ? std::numeric_limits<std::size_t>::max() :
					parse_opts & Flags_Vector_Parse::ItemsAtOnce ? 1 :
					checkVecLength && (parse_opts & Flags_Vector_Parse::ItemsLineByLine) ? lenNextVector : 0;

				// Above were considered all the possible cases, so this condition will never
				// be executed, unless new conditions appear
				if (line_to_read == 0)
				{
					_state = State::WrongReadConfiguration;
					break;
				}

				// Load vector's elements
				split(fstream, storageItem, line_to_read);

				// Check if vectors are equal
				if (checkVecEquality)
				{
					if (lenAllVectors == 0)
						lenAllVectors = storageItem.size();
					else if (lenAllVectors != storageItem.size())
					{
						_state = State::VectorsHaveDifferentLength;
						break;
					}
				}

				// Check if given length for vector items is valid
				if (checkVecLength && lenNextVector != storageItem.size())
				{
					_state = State::VectorItemsWrongNumber;
					break;
				}

				// Add vector to the storage
				_storageVector.push_back(storageItem);
			}

			fstream.close();
		}

		// Parse input file for matrix-based data
		void read_matrix(unsigned check_opts = Flags::NullOpts,
			unsigned parse_opts = Flags_Matrix_Parse::DimentionsAtOnce, Kind type = Kind::Matrix)
		{
			std::string line, line1, line2;
			std::fstream fstream;
			std::stringstream sstream;

			std::vector<U> storageItem;

			fstream.open(_file, std::ios_base::in);

			if (!fstream.is_open())
			{
				_state = State::FileAccessError;
				return;
			}

			_storageMatrix.clear();

			if (parse_opts & Flags_Matrix_Parse::DimentionsLineByLine)
			{
				std::getline(fstream, line1);
				std::getline(fstream, line2);

				// Row
				sstream.str(line1);
				sstream >> sizeRow;
				sstream.clear();

				// Col
				sstream.str(line2);
				sstream >> sizeCol;
				sstream.clear();
			}
			else if (parse_opts & Flags_Matrix_Parse::DimentionsAtOnce)
			{
				std::getline(fstream, line);
				sstream.str(line);
				sstream >> sizeRow >> sizeCol;
				sstream.clear();
			}
			else
			{
				_state = State::WrongReadConfiguration;
				return;
			}

			// Load matrix data
			_storageMatrix.reserve(sizeRow * sizeCol);
			storageItem.reserve(sizeCol);

			auto cnt = sizeRow;
			while (cnt--)
			{
				// Load vector's elements
				storageItem.clear();
				split(fstream, storageItem, 1);

				std::move(storageItem.begin(), storageItem.end(), std::back_inserter(_storageMatrix));
			}

			// Check matrix's elements length
			if (_storageMatrix.size() != sizeRow * sizeCol)
			{
				_state = State::VectorItemsWrongNumber;
				return;
			}

			fstream.close();
		}
	};
}
<commit_msg>Option flags: create separate namespaces<commit_after>#pragma once

#include <limits>
#include <vector>
#include <string>
#include <fstream>
#include <sstream>
#include <type_traits>

namespace DataLoader
{
	enum class Kind
	{
		Arbitrary,
		Vector,
		Matrix
	};

	namespace Flags
	{
		// No Flags
		const unsigned NullOpts = 0;

		namespace Arbitrary
		{
			/*
			-- Work with arbitrary values/numbers
			*/

			namespace Parse
			{
				// If met delimeter separated values, read one by one
				const unsigned Separately = 1;

				// If met delimeter separated values, read as vector
				const unsigned Continuously = (1 << 1);
			}

			namespace Check {}
		}

		namespace Vector
		{
			namespace Parse
			{
				// Read vector's size first (automatically check for items count)
				const unsigned Size = 1;

				// Read vector's elements line by line
				const unsigned ItemsLineByLine = (1 << 1);

				// Read vector's elements at one as a delimeter-separated string
				const unsigned ItemsAtOnce = (1 << 2);
			}

			namespace Check
			{
				// All loaded vectors should have the same length
				const unsigned LengthEquality = (1 << 3);
			}
		}

		namespace Matrix
		{
			/*
				-- Work with only 2D matrix
				-- Matrix should always has dimentions being put before the data
				-- The number of rows and columns are checked after full read
			*/

			namespace Parse
			{
				// Read dimentions: each value on separate line {val_1 \n val_2}
				const unsigned DimentionsLineByLine = 1;

				// Read dimentions: both values on the same line {val_1 <delim> val_2 }
				const unsigned DimentionsAtOnce = (1 << 1);
			}

			namespace Check {}
		}
	}

	// Namespace Aliases
	namespace Flags_Arbitrary_Parse = Flags::Arbitrary::Parse;
	namespace Flags_Arbitrary_Check = Flags::Arbitrary::Check;
	namespace Flags_Vector_Parse = Flags::Vector::Parse;
	namespace Flags_Vector_Check = Flags::Vector::Check;
	namespace Flags_Matrix_Parse = Flags::Matrix::Parse;
	namespace Flags_Matrix_Check = Flags::Matrix::Check;

	namespace State
	{
		const unsigned Idle = 1; // ok
		const unsigned FileAccessError = (1 << 1); // bad
		const unsigned FileReadFormatError = (1 << 2); // fail
		const unsigned FileReadFailure = (1 << 3); // bad/ios::bad
		const unsigned VectorItemsWrongNumber = (1 << 4); // fail
		const unsigned VectorsHaveDifferentLength = (1 << 4); // fail
		const unsigned WrongReadConfiguration = (1 << 5); // fail
		const unsigned VectorInvalidIndex = (1 << 5); // bad
	}

	// Restricting the usage of Loader class
	template<class U>
	struct EnableForArithmeticType {
		typedef typename std::enable_if<std::is_arithmetic<U>::value>::type type;
	};

	template<typename U, typename Enable = EnableForArithmeticType<U>::type>
	class Loader
	{
	private:

		// Name of the input data file
		std::string _file;

		// Default delimeter
		char _delimeter{ ',' };

		// Reader state
		unsigned _state{ State::Idle };

		// Service variables
		size_t sizeRow{ 0 }, sizeCol{ 0 };

		// Storage for read data
		std::vector<std::vector<U>> _storageVector;
		std::vector<U> _storageMatrix;

		void split(std::fstream& stream, std::vector<U>& storage, size_t lines_to_read)
		{
			std::string line;
			std::stringstream sstream;
			std::stringstream sconvert;
			std::string item;
			U num;

			while (!stream.eof() && lines_to_read--)
			{
				// Read vector's items
				std::getline(stream, line);

				if (!stream.eof() && stream.rdstate() != std::ios::goodbit)
				{
					if (stream.fail()) _state = State::FileReadFormatError;
					if (stream.bad()) _state = State::FileReadFailure;
					break;
				}

				sstream.str(line);
				while (std::getline(sstream, item, _delimeter)) {
					sconvert.str(item);
					sconvert >> num;
					sconvert.clear();
					storage.push_back(num);
				}

				sstream.clear();
			}
		}

	public:

		explicit Loader(std::string file) : _file(file) {};

		// Settings: change delimeter character (',' by default)
		inline void delimeter(char delimeter) { _delimeter = delimeter; }

		// Service: get current state
		inline unsigned state() const { return _state; }

		// Service: state check aliases
		inline bool is_ok() const { return _state == State::Idle; };
		inline bool is_bad() const {
			return
				_state == State::FileAccessError ||
				_state == State::FileReadFailure ||
				_state == State::VectorInvalidIndex;
		};
		inline bool is_fail() const { return !is_ok() && !is_bad(); };

		// Service: reset internal state
		void refresh()
		{
			_state = State::Idle;
			_storageVector.clear();
		}

		// Service: get vector length
		size_t arg_vector_len(size_t idx)
		{
			if (idx >= _storageVector.size())
			{
				_state = State::VectorInvalidIndex;
				return std::numeric_limits<size_t>::max();
			}

			return _storageVector[idx].size();
		}

		// Return i-th vector
		std::vector<U> arg_vector(size_t idx)
		{
			if (idx >= _storageVector.size())
				return std::vector<U>{};

			return _storageVector[idx];
		};

		// Fill in given vector storage
		void arg_vector(size_t idx, std::vector<U>& storage)
		{
			if (idx >= _storageVector.size())
				return;

			storage.clear();
			storage.reserve(_storageVector[idx].size());
			std::copy(_storageVector[idx].begin(), _storageVector[idx].end(), std::back_inserter(storage));
		};

		// Fill in given array storage
		void arg_vector(size_t idx, U* storage)
		{
			if (!storage || idx >= _storageVector.size())
				return;

			for (auto v : _storageVector[idx])
				*storage++ = U(v);
		}

		// Return flattened matrix
		std::vector<U> arg_matrix()
		{
			return _storageMatrix;
		}

		// Fill in given array storage
		void arg_matrix(U* storage)
		{
			if (!storage)
				return;

			for (auto v : _storageMatrix)
				*storage++ = U(v);
		}

		void arg_matrix_dims(int& row, int& col)
		{
			row = sizeRow;
			col = sizeCol;
		}

		// Parse input file without data specification
		void read_arbitrary(unsigned check_opts = Flags::NullOpts,
			unsigned parse_opts = Flags_Arbitrary_Parse::Separately, Kind type = Kind::Arbitrary)
		{}

		// Parse input file for vector-based data
		void read_vector(unsigned check_opts = Flags::NullOpts,
			unsigned parse_opts = Flags_Vector_Parse::ItemsAtOnce, Kind type = Kind::Vector)
		{
			size_t lenNextVector{ 0 }, lenAllVectors{ 0 };
			std::string line, line1, line2;
			std::fstream fstream;
			std::istringstream sstream;

			fstream.open(_file, std::ios_base::in);

			if (!fstream.is_open())
			{
				_state = State::FileAccessError;
				return;
			}

			_storageVector.clear();

			// Validate vector length if appropriate option is given
			bool checkVecLength = parse_opts & Flags_Vector_Parse::Size;
			// For each vector given check if items number remains the same
			bool checkVecEquality = check_opts & Flags_Vector_Check::LengthEquality;
			// If no Size is given and parse option is set to ItemsLineByLine,
			// we are to read in one vector storage until the end of the file
			bool readUntilEOF = !checkVecLength && (parse_opts & Flags_Vector_Parse::ItemsLineByLine);

			while (fstream.good())
			{
				std::vector<U> storageItem;

				// Read vector's length
				if (checkVecLength && std::getline(fstream, line))
				{
					sstream.str(line);
					sstream >> lenNextVector;
					sstream.clear();

					storageItem.reserve(lenNextVector);
				}

				size_t line_to_read = { 0 };
				// How many lines we need to read for a vector to be filled?
				//  -- if "ReadUntilEOF" flag is set, read until the EOF (lines to read = MAX(size_t))
				//  -- if "ItemsAtOnce" flag is set, read one line no matter if we are given size or not
				//  -- last case: flag "ItemsLineByLine" is set and "Size" flag is given, read "LenNextVector" lines
				line_to_read =
					readUntilEOF ? std::numeric_limits<std::size_t>::max() :
					parse_opts & Flags_Vector_Parse::ItemsAtOnce ? 1 :
					checkVecLength && (parse_opts & Flags_Vector_Parse::ItemsLineByLine) ? lenNextVector : 0;

				// Above were considered all the possible cases, so this condition will never
				// be executed, unless new conditions appear
				if (line_to_read == 0)
				{
					_state = State::WrongReadConfiguration;
					break;
				}

				// Load vector's elements
				split(fstream, storageItem, line_to_read);

				// Check if vectors are equal
				if (checkVecEquality)
				{
					if (lenAllVectors == 0)
						lenAllVectors = storageItem.size();
					else if (lenAllVectors != storageItem.size())
					{
						_state = State::VectorsHaveDifferentLength;
						break;
					}
				}

				// Check if given length for vector items is valid
				if (checkVecLength && lenNextVector != storageItem.size())
				{
					_state = State::VectorItemsWrongNumber;
					break;
				}

				// Add vector to the storage
				_storageVector.push_back(storageItem);
			}

			fstream.close();
		}

		// Parse input file for matrix-based data
		void read_matrix(unsigned check_opts = Flags::NullOpts,
			unsigned parse_opts = Flags_Matrix_Parse::DimentionsAtOnce, Kind type = Kind::Matrix)
		{
			std::string line, line1, line2;
			std::fstream fstream;
			std::stringstream sstream;

			std::vector<U> storageItem;

			fstream.open(_file, std::ios_base::in);

			if (!fstream.is_open())
			{
				_state = State::FileAccessError;
				return;
			}

			_storageMatrix.clear();

			if (parse_opts & Flags_Matrix_Parse::DimentionsLineByLine)
			{
				std::getline(fstream, line1);
				std::getline(fstream, line2);

				// Row
				sstream.str(line1);
				sstream >> sizeRow;
				sstream.clear();

				// Col
				sstream.str(line2);
				sstream >> sizeCol;
				sstream.clear();
			}
			else if (parse_opts & Flags_Matrix_Parse::DimentionsAtOnce)
			{
				std::getline(fstream, line);
				sstream.str(line);
				sstream >> sizeRow >> sizeCol;
				sstream.clear();
			}
			else
			{
				_state = State::WrongReadConfiguration;
				return;
			}

			// Load matrix data
			_storageMatrix.reserve(sizeRow * sizeCol);
			storageItem.reserve(sizeCol);

			auto cnt = sizeRow;
			while (cnt--)
			{
				// Load vector's elements
				storageItem.clear();
				split(fstream, storageItem, 1);

				std::move(storageItem.begin(), storageItem.end(), std::back_inserter(_storageMatrix));
			}

			// Check matrix's elements length
			if (_storageMatrix.size() != sizeRow * sizeCol)
			{
				_state = State::VectorItemsWrongNumber;
				return;
			}

			fstream.close();
		}
	};
}
<|endoftext|>


<commit_before>#include "Resolver.h"
#include <muduo/base/Logging.h>
#include <muduo/net/Channel.h>
#include <muduo/net/EventLoop.h>
#include <boost/bind.hpp>

#include "udns.h"
#include <assert.h>
#include <stdio.h>

namespace
{

int init_udns()
{
  static bool initialized = false;
  if (!initialized)
    ::dns_init(NULL, 0);
  initialized = true;
  return 1;
}

struct UdnsInitializer
{
  UdnsInitializer()
  {
    init_udns();
  }

  ~UdnsInitializer()
  {
    ::dns_reset(NULL);
  }
};

UdnsInitializer udnsInitializer;

const bool kDebug = false;
}

using namespace muduo::net;

Resolver::Resolver(EventLoop* loop)
  : loop_(loop),
    ctx_(NULL),
    fd_(-1),
    timerActive_(false)
{
  init_udns();
  ctx_ = ::dns_new(NULL);
  assert(ctx_ != NULL);
  ::dns_set_opt(ctx_, DNS_OPT_TIMEOUT, 2);
}

Resolver::~Resolver()
{
  channel_->disableAll();
  channel_->remove();
  ::dns_free(ctx_);
}

void Resolver::start()
{
  fd_ = ::dns_open(ctx_);
  channel_.reset(new Channel(loop_, fd_));
  channel_->setReadCallback(boost::bind(&Resolver::onRead, this, _1));
  channel_->enableReading();
}

bool Resolver::resolve(const StringPiece& hostname, const Callback& cb)
{
  loop_->assertInLoopThread();
  QueryData* queryData = new QueryData(this, cb);
  time_t now = time(NULL);
  struct dns_query* query =
    ::dns_submit_a4(ctx_, hostname.data(), 0, &Resolver::dns_query_a4, queryData);
  int timeout = ::dns_timeouts(ctx_, -1, now);
  LOG_DEBUG << "timeout " <<  timeout << " active " << timerActive_ << " " << queryData;
  if (!timerActive_)
  {
    loop_->runAfter(timeout, boost::bind(&Resolver::onTimer, this));
    timerActive_ = true;
  }
  return query != NULL;
}

void Resolver::onRead(Timestamp t)
{
  LOG_DEBUG << "onRead " << t.toString();
  ::dns_ioevent(ctx_, t.secondsSinceEpoch());
}

void Resolver::onTimer()
{
  assert(timerActive_ == true);
  time_t now = loop_->pollReturnTime().secondsSinceEpoch();
  int timeout = ::dns_timeouts(ctx_, -1, now);
  LOG_DEBUG << "onTimer " << loop_->pollReturnTime().toString()
            << " timeout " <<  timeout;

  if (timeout < 0)
  {
    timerActive_ = false;
  }
  else
  {
    loop_->runAfter(timeout, boost::bind(&Resolver::onTimer, this));
  }
}

void Resolver::onQueryResult(struct dns_rr_a4 *result, const Callback& callback)
{
  int status = ::dns_status(ctx_);
  LOG_DEBUG << "onQueryResult " << status;
  struct sockaddr_in addr;
  bzero(&addr, sizeof addr);
  addr.sin_family = AF_INET;
  addr.sin_port = 0;
  if (result)
  {
    if (kDebug)
    {
      printf("cname %s\n", result->dnsa4_cname);
      printf("qname %s\n", result->dnsa4_qname);
      printf("ttl %d\n", result->dnsa4_ttl);
      printf("nrr %d\n", result->dnsa4_nrr);
      for (int i = 0; i < result->dnsa4_nrr; ++i)
      {
        char buf[32];
        ::dns_ntop(AF_INET, &result->dnsa4_addr[i], buf, sizeof buf);
        printf("  %s\n", buf);
      }
    }
    addr.sin_addr = result->dnsa4_addr[0];
  }
  InetAddress inet(addr);
  callback(inet);
}

void Resolver::dns_query_a4(struct dns_ctx *ctx, struct dns_rr_a4 *result, void *data)
{
  QueryData* query = static_cast<QueryData*>(data);

  assert(ctx == query->owner->ctx_);
  query->owner->onQueryResult(result, query->callback);
  free(result);
  delete query;
}

<commit_msg>add miss constructor (#1)<commit_after>#include "Resolver.h"
#include <muduo/base/Logging.h>
#include <muduo/net/Channel.h>
#include <muduo/net/EventLoop.h>
#include <boost/bind.hpp>

#include "udns.h"
#include <assert.h>
#include <stdio.h>

namespace
{

int init_udns()
{
  static bool initialized = false;
  if (!initialized)
    ::dns_init(NULL, 0);
  initialized = true;
  return 1;
}

struct UdnsInitializer
{
  UdnsInitializer()
  {
    init_udns();
  }

  ~UdnsInitializer()
  {
    ::dns_reset(NULL);
  }
};

UdnsInitializer udnsInitializer;

const bool kDebug = false;
}

using namespace muduo::net;

Resolver::Resolver(EventLoop* loop)
  : loop_(loop),
    ctx_(NULL),
    fd_(-1),
    timerActive_(false)
{
  init_udns();
  ctx_ = ::dns_new(NULL);
  assert(ctx_ != NULL);
  ::dns_set_opt(ctx_, DNS_OPT_TIMEOUT, 2);
}

Resolver::Resolver(EventLoop *loop, const InetAddress &nameServer):
    loop_(loop),
    ctx_(NULL),
    fd_(-1),
    timerActive_(false)
{
    init_udns();
    ctx_ = ::dns_new(NULL);
    assert(ctx_ != NULL);
    ::dns_add_serv_s(ctx_, nameServer.getSockAddr());
    ::dns_set_opt(ctx_, DNS_OPT_TIMEOUT, 2);
}

Resolver::~Resolver()
{
  channel_->disableAll();
  channel_->remove();
  ::dns_free(ctx_);
}

void Resolver::start()
{
  fd_ = ::dns_open(ctx_);
  channel_.reset(new Channel(loop_, fd_));
  channel_->setReadCallback(boost::bind(&Resolver::onRead, this, _1));
  channel_->enableReading();
}

bool Resolver::resolve(const StringPiece& hostname, const Callback& cb)
{
  loop_->assertInLoopThread();
  QueryData* queryData = new QueryData(this, cb);
  time_t now = time(NULL);
  struct dns_query* query =
    ::dns_submit_a4(ctx_, hostname.data(), 0, &Resolver::dns_query_a4, queryData);
  int timeout = ::dns_timeouts(ctx_, -1, now);
  LOG_DEBUG << "timeout " <<  timeout << " active " << timerActive_ << " " << queryData;
  if (!timerActive_)
  {
    loop_->runAfter(timeout, boost::bind(&Resolver::onTimer, this));
    timerActive_ = true;
  }
  return query != NULL;
}

void Resolver::onRead(Timestamp t)
{
  LOG_DEBUG << "onRead " << t.toString();
  ::dns_ioevent(ctx_, t.secondsSinceEpoch());
}

void Resolver::onTimer()
{
  assert(timerActive_ == true);
  time_t now = loop_->pollReturnTime().secondsSinceEpoch();
  int timeout = ::dns_timeouts(ctx_, -1, now);
  LOG_DEBUG << "onTimer " << loop_->pollReturnTime().toString()
            << " timeout " <<  timeout;

  if (timeout < 0)
  {
    timerActive_ = false;
  }
  else
  {
    loop_->runAfter(timeout, boost::bind(&Resolver::onTimer, this));
  }
}

void Resolver::onQueryResult(struct dns_rr_a4 *result, const Callback& callback)
{
  int status = ::dns_status(ctx_);
  LOG_DEBUG << "onQueryResult " << status;
  struct sockaddr_in addr;
  bzero(&addr, sizeof addr);
  addr.sin_family = AF_INET;
  addr.sin_port = 0;
  if (result)
  {
    if (kDebug)
    {
      printf("cname %s\n", result->dnsa4_cname);
      printf("qname %s\n", result->dnsa4_qname);
      printf("ttl %d\n", result->dnsa4_ttl);
      printf("nrr %d\n", result->dnsa4_nrr);
      for (int i = 0; i < result->dnsa4_nrr; ++i)
      {
        char buf[32];
        ::dns_ntop(AF_INET, &result->dnsa4_addr[i], buf, sizeof buf);
        printf("  %s\n", buf);
      }
    }
    addr.sin_addr = result->dnsa4_addr[0];
  }
  InetAddress inet(addr);
  callback(inet);
}

void Resolver::dns_query_a4(struct dns_ctx *ctx, struct dns_rr_a4 *result, void *data)
{
  QueryData* query = static_cast<QueryData*>(data);

  assert(ctx == query->owner->ctx_);
  query->owner->onQueryResult(result, query->callback);
  free(result);
  delete query;
}

<|endoftext|>


<commit_before>#include <avr/io.h>
#include <util/delay.h>
#include <OS.hpp>
#include <avr/interrupt.h>
#include "drivers/serial.hpp"

Serial serial;

void Task1() {
    while (1) {
        static uint8_t i = 0;
        PORTB ^= (1 << PB2);
        _delay_ms(50);
        serial.printf("Test %d\r\n", i);
        i++;
    }
}

void Task2() {
    while (1) {
        PORTB ^= (1 << PB1);
        _delay_ms(100);
    }
}

void Task3() {
    while (1) {
        PORTB ^= (1 << PB0);
        _delay_ms(200);
    }
}

int main() {
    // TP ONLY BEGIN
    serial.init(9600U);
    DDRB = (1 << PB0)|(1 << PB1)|(1 << PB2);
    PORTB = 0;

    sys::taskCreate(&Task1, 0, 0xFF);
    sys::taskCreate(&Task2, 0, 0x10);
    sys::taskCreate(&Task3, 0, 0x10);

    // TP ONLY END

    sys::boot();

    return 0;
}
<commit_msg>mutex instance<commit_after>#include <avr/io.h>
#include <util/delay.h>
#include <OS.hpp>
#include <avr/interrupt.h>
#include "drivers/serial.hpp"

Serial serial;

mutex muteks_01;

void Task1() {
    while (1) {
        static uint8_t i = 0;
        PORTB ^= (1 << PB2);
        _delay_ms(50);
        serial.printf("Test %d\r\n", i);
        i++;
    }
}

void Task2() {
    while (1) {
        PORTB ^= (1 << PB1);
        _delay_ms(100);
    }
}

void Task3() {
    while (1) {
        PORTB ^= (1 << PB0);
        _delay_ms(200);
    }
}

int main() {
    // TP ONLY BEGIN
    serial.init(9600U);
    DDRB = (1 << PB0)|(1 << PB1)|(1 << PB2);
    PORTB = 0;

    sys::taskCreate(&Task1, 0, 0xFF);
    sys::taskCreate(&Task2, 0, 0x20);
    sys::taskCreate(&Task3, 0, 0x20);

    // TP ONLY END

    sys::boot();

    return 0;
}
<|endoftext|>


<commit_before>/**
 * Simple Image Processing Library
 * Copyright Erik Smistad 2012
 * See LICENSE file for information on use
 */

#ifndef SIPL_EXCEPTIONS
#define SIPL_EXCEPTIONS

#include <exception>
#include <stdio.h>

class SIPLException : public std::exception {
    public:
        SIPLException() {
            this->line = -1;
        };
        SIPLException(char * message) {
            this->line = -1;
            this->message = message;
        };
        SIPLException(int line, char * file) {
            this->line = line;
            this->file = file;
        };
        SIPLException(char * message, int line, char * file) {
            this->message = message;
            this->line = line;
            this->file = file;
        };
        virtual const char * what() const throw() {
            char * string = new char[255];
            if(line > -1) {
                sprintf(string, "%s \nException thrown at line %d in file %s", message, line, file);
                return string;
            } else {
                return message;
            }
        };
        void setLine(int line) {
            this->line = line;
        };
        void setFile(const char * file) {
            this->file = file;
        };
        void setMessage(char * message) {
            this->message = message;
        };
    private:
        int line;
        const char * file;
        char * message;
};

class IOException : public SIPLException {
    public:
        IOException() {
        };
        IOException(const char * filename, int line, const char * file) {
            this->filename = filename;
            char * message = new char[255];
            sprintf(message, "IO Error with file %s", filename);
            this->setMessage(message);
            this->setLine(line);
            this->setFile(file);
        };
        IOException(const char * filename) {
            this->filename = filename;
            char * message = new char[255];
            sprintf(message, "IO Error with file %s", filename);
            this->setMessage(message);
        };
    protected:
        const char * filename;
};

class FileNotFoundException : public IOException {
    public:
        FileNotFoundException(const char * filename) {
            this->filename = filename;
            char * message = new char[255];
            sprintf(message, "The following file was not found: %s", filename);
            this->setMessage(message);
        };
        FileNotFoundException(const char * filename, int line, const char * file) {
            this->filename = filename;
            char * message = new char[255];
            sprintf(message, "The following file was not found: %s", filename);
            this->setMessage(message);
            this->setLine(line);
            this->setFile(file);
        };
};

class OutOfBoundsException : public SIPLException {
    public:
        OutOfBoundsException(int x, int sizeX) {
            this->x = x;
            this->sizeX = sizeX;
            char * message = new char[255];
            sprintf(message, "Out of bounds exception. Requested position %d in image of size %d", x, sizeX);
            this->setMessage(message);
        };
        OutOfBoundsException(int x, int sizeX, int line, const char * file) {
            this->x = x;
            this->sizeX = sizeX;
            char * message = new char[255];
            sprintf(message, "Out of bounds exception. Requested position %d in image of size %d", x, sizeX);
            this->setMessage(message);
            this->setLine(line);
            this->setFile(file);
        };

        OutOfBoundsException(int x, int y, int sizeX, int sizeY) {
            this->x = x;
            this->y = y;
            this->sizeX = sizeX;
            this->sizeY = sizeY;
            char * message = new char[255];
            sprintf(message, "Out of bounds exception. Requested position %d, %d in image of size %d, %d", x, y, sizeX, sizeY);
            this->setMessage(message);
        };
        OutOfBoundsException(int x, int y, int sizeX, int sizeY, int line, const char * file) {
            this->x = x;
            this->y = y;
            this->sizeX = sizeX;
            this->sizeY = sizeY;
            char * message = new char[255];
            sprintf(message, "Out of bounds exception. Requested position %d, %d in image of size %d, %d", x, y, sizeX, sizeY);
            this->setMessage(message);
            this->setLine(line);
            this->setFile(file);
        };
        OutOfBoundsException(int x, int y, int z, int sizeX, int sizeY, int sizeZ) {
            this->x = x;
            this->y = y;
            this->y = z;
            this->sizeX = sizeX;
            this->sizeY = sizeY;
            this->sizeZ = sizeZ;
            char * message = new char[255];
            sprintf(message, "Out of bounds exception. Requested position %d, %d, %d in volume of size %d, %d, %d", x, y, z, sizeX, sizeY, sizeZ);
            this->setMessage(message);
        };
        OutOfBoundsException(int x, int y, int z, int sizeX, int sizeY, int sizeZ, int line, const char * file) {
            this->x = x;
            this->y = y;
            this->y = z;
            this->sizeX = sizeX;
            this->sizeY = sizeY;
            this->sizeZ = sizeZ;
            char * message = new char[255];
            sprintf(message, "Out of bounds exception. Requested position %d, %d, %d in volume of size %d, %d, %d", x, y, z, sizeX, sizeY, sizeZ);
            this->setMessage(message);
            this->setLine(line);
            this->setFile(file);
       };
    private:
        int x, y, z; // position requested
        int sizeX, sizeY, sizeZ;
};

class ConversionException : public SIPLException {
};

#endif
<commit_msg>added const to some char arrays<commit_after>/**
 * Simple Image Processing Library
 * Copyright Erik Smistad 2012
 * See LICENSE file for information on use
 */

#ifndef SIPL_EXCEPTIONS
#define SIPL_EXCEPTIONS

#include <exception>
#include <stdio.h>
namespace SIPL {

class SIPLException : public std::exception {
    public:
        SIPLException() {
            this->line = -1;
        };
        SIPLException(const char * message) {
            this->line = -1;
            this->message = message;
        };
        SIPLException(int line, char * file) {
            this->line = line;
            this->file = file;
        };
        SIPLException(const char * message, int line, char * file) {
            this->message = message;
            this->line = line;
            this->file = file;
        };
        virtual const char * what() const throw() {
            char * string = new char[255];
            if(line > -1) {
                sprintf(string, "%s \nException thrown at line %d in file %s", message, line, file);
                return string;
            } else {
                return message;
            }
        };
        void setLine(int line) {
            this->line = line;
        };
        void setFile(const char * file) {
            this->file = file;
        };
        void setMessage(const char * message) {
            this->message = message;
        };
    private:
        int line;
        const char * file;
        const char * message;
};

class IOException : public SIPLException {
    public:
        IOException() {
        };
        IOException(const char * filename, int line, const char * file) {
            this->filename = filename;
            char * message = new char[255];
            sprintf(message, "IO Error with file %s", filename);
            this->setMessage(message);
            this->setLine(line);
            this->setFile(file);
        };
        IOException(const char * filename) {
            this->filename = filename;
            char * message = new char[255];
            sprintf(message, "IO Error with file %s", filename);
            this->setMessage(message);
        };
    protected:
        const char * filename;
};

class FileNotFoundException : public IOException {
    public:
        FileNotFoundException(const char * filename) {
            this->filename = filename;
            char * message = new char[255];
            sprintf(message, "The following file was not found: %s", filename);
            this->setMessage(message);
        };
        FileNotFoundException(const char * filename, int line, const char * file) {
            this->filename = filename;
            char * message = new char[255];
            sprintf(message, "The following file was not found: %s", filename);
            this->setMessage(message);
            this->setLine(line);
            this->setFile(file);
        };
};

class OutOfBoundsException : public SIPLException {
    public:
        OutOfBoundsException(int x, int sizeX) {
            this->x = x;
            this->sizeX = sizeX;
            char * message = new char[255];
            sprintf(message, "Out of bounds exception. Requested position %d in image of size %d", x, sizeX);
            this->setMessage(message);
        };
        OutOfBoundsException(int x, int sizeX, int line, const char * file) {
            this->x = x;
            this->sizeX = sizeX;
            char * message = new char[255];
            sprintf(message, "Out of bounds exception. Requested position %d in image of size %d", x, sizeX);
            this->setMessage(message);
            this->setLine(line);
            this->setFile(file);
        };

        OutOfBoundsException(int x, int y, int sizeX, int sizeY) {
            this->x = x;
            this->y = y;
            this->sizeX = sizeX;
            this->sizeY = sizeY;
            char * message = new char[255];
            sprintf(message, "Out of bounds exception. Requested position %d, %d in image of size %d, %d", x, y, sizeX, sizeY);
            this->setMessage(message);
        };
        OutOfBoundsException(int x, int y, int sizeX, int sizeY, int line, const char * file) {
            this->x = x;
            this->y = y;
            this->sizeX = sizeX;
            this->sizeY = sizeY;
            char * message = new char[255];
            sprintf(message, "Out of bounds exception. Requested position %d, %d in image of size %d, %d", x, y, sizeX, sizeY);
            this->setMessage(message);
            this->setLine(line);
            this->setFile(file);
        };
        OutOfBoundsException(int x, int y, int z, int sizeX, int sizeY, int sizeZ) {
            this->x = x;
            this->y = y;
            this->y = z;
            this->sizeX = sizeX;
            this->sizeY = sizeY;
            this->sizeZ = sizeZ;
            char * message = new char[255];
            sprintf(message, "Out of bounds exception. Requested position %d, %d, %d in volume of size %d, %d, %d", x, y, z, sizeX, sizeY, sizeZ);
            this->setMessage(message);
        };
        OutOfBoundsException(int x, int y, int z, int sizeX, int sizeY, int sizeZ, int line, const char * file) {
            this->x = x;
            this->y = y;
            this->y = z;
            this->sizeX = sizeX;
            this->sizeY = sizeY;
            this->sizeZ = sizeZ;
            char * message = new char[255];
            sprintf(message, "Out of bounds exception. Requested position %d, %d, %d in volume of size %d, %d, %d", x, y, z, sizeX, sizeY, sizeZ);
            this->setMessage(message);
            this->setLine(line);
            this->setFile(file);
       };
    private:
        int x, y, z; // position requested
        int sizeX, sizeY, sizeZ;
};

class ConversionException : public SIPLException {
};

}; // END NAMESPACE SIPL

#endif
<|endoftext|>