<commit_before>#pragma once

#include <string>

#include "common.hpp"
#include "x11/color.hpp"
#include "x11/randr.hpp"

POLYBAR_NS

enum class edge : uint8_t { NONE = 0U, TOP, BOTTOM, LEFT, RIGHT, ALL };

enum class alignment : uint8_t { NONE = 0U, LEFT, CENTER, RIGHT };

enum class attribute : uint8_t { NONE = 0U, UNDERLINE, OVERLINE };

enum class syntaxtag : uint8_t {
  NONE = 0U,
  A,  // mouse action
  B,  // background color
  F,  // foreground color
  T,  // font index
  O,  // pixel offset
  R,  // flip colors
  o,  // overline color
  u,  // underline color
};

enum class mousebtn : uint8_t { NONE = 0U, LEFT, MIDDLE, RIGHT, SCROLL_UP, SCROLL_DOWN, DOUBLE_CLICK };

enum class strut : uint16_t {
  LEFT = 0U,
  RIGHT,
  TOP,
  BOTTOM,
  LEFT_START_Y,
  LEFT_END_Y,
  RIGHT_START_Y,
  RIGHT_END_Y,
  TOP_START_X,
  TOP_END_X,
  BOTTOM_START_X,
  BOTTOM_END_X,
};

struct position {
  int16_t x{0};
  int16_t y{0};
};

struct size {
  uint16_t w{1U};
  uint16_t h{1U};
};

struct side_values {
  uint16_t left{0U};
  uint16_t right{0U};
};

struct edge_values {
  uint16_t left{0U};
  uint16_t right{0U};
  uint16_t top{0U};
  uint16_t bottom{0U};
};

struct border_settings {
  uint32_t color{0xFF000000};
  uint16_t size{0U};
};

struct line_settings {
  uint32_t color{0xFF000000};
  uint16_t size{0U};
};

struct action {
  mousebtn button{mousebtn::NONE};
  string command{};
};

struct action_block : public action {
  alignment align{alignment::NONE};
  volatile double start_x{0.0};
  volatile double end_x{0.0};
  bool active{true};

  uint16_t width() const {
    return static_cast<uint16_t>(end_x - start_x + 0.5);
  }
};

struct bar_settings {
  explicit bar_settings() = default;
  bar_settings(const bar_settings& other) = default;

  xcb_window_t window{XCB_NONE};
  monitor_t monitor{};
  edge origin{edge::TOP};
  struct size size {
    1U, 1U
  };
  position pos{0, 0};
  position offset{0, 0};
  position center{0, 0};
  side_values padding{0U, 0U};
  side_values margin{0U, 0U};
  side_values module_margin{0U, 2U};
  edge_values strut{0U, 0U, 0U, 0U};

  uint32_t background{0xFFFFFFFF};
  uint32_t foreground{0xFF000000};

  line_settings underline{};
  line_settings overline{};

  std::unordered_map<edge, border_settings> borders{};

  uint8_t spacing{1U};
  string separator{};

  string wmname{};
  string locale{};

  bool override_redirect{false};

  vector<action> actions{};

  bool dimmed{false};
  double dimvalue{1.0};

  const xcb_rectangle_t inner_area(bool abspos = false) const {
    xcb_rectangle_t rect{0, 0, size.w, size.h};

    if (abspos) {
      rect.x = pos.x;
      rect.y = pos.y;
    }
    if (borders.find(edge::TOP) != borders.end()) {
      rect.y += borders.at(edge::TOP).size;
      rect.height -= borders.at(edge::TOP).size;
    }
    if (borders.find(edge::BOTTOM) != borders.end()) {
      rect.height -= borders.at(edge::BOTTOM).size;
    }
    if (borders.find(edge::LEFT) != borders.end()) {
      rect.x += borders.at(edge::LEFT).size;
      rect.width -= borders.at(edge::LEFT).size;
    }
    if (borders.find(edge::RIGHT) != borders.end()) {
      rect.width -= borders.at(edge::RIGHT).size;
    }
    return rect;
  }
};

struct event_timer {
  xcb_timestamp_t event{0L};
  xcb_timestamp_t offset{1L};

  bool allow(xcb_timestamp_t time) {
    bool pass = time >= event + offset;
    event = time;
    return pass;
  };

  bool deny(xcb_timestamp_t time) {
    return !allow(time);
  };
};

POLYBAR_NS_END
<commit_msg>fix: Use enum_hash for unordered_map<commit_after>#pragma once

#include <string>

#include "common.hpp"
#include "x11/color.hpp"
#include "x11/randr.hpp"

POLYBAR_NS

struct enum_hash {
  template <typename T>
  inline typename std::enable_if<std::is_enum<T>::value, size_t>::type operator()(T const value) const {
    return static_cast<size_t>(value);
  }
};

enum class edge : uint8_t { NONE = 0U, TOP, BOTTOM, LEFT, RIGHT, ALL };

enum class alignment : uint8_t { NONE = 0U, LEFT, CENTER, RIGHT };

enum class attribute : uint8_t { NONE = 0U, UNDERLINE, OVERLINE };

enum class syntaxtag : uint8_t {
  NONE = 0U,
  A,  // mouse action
  B,  // background color
  F,  // foreground color
  T,  // font index
  O,  // pixel offset
  R,  // flip colors
  o,  // overline color
  u,  // underline color
};

enum class mousebtn : uint8_t { NONE = 0U, LEFT, MIDDLE, RIGHT, SCROLL_UP, SCROLL_DOWN, DOUBLE_CLICK };

enum class strut : uint16_t {
  LEFT = 0U,
  RIGHT,
  TOP,
  BOTTOM,
  LEFT_START_Y,
  LEFT_END_Y,
  RIGHT_START_Y,
  RIGHT_END_Y,
  TOP_START_X,
  TOP_END_X,
  BOTTOM_START_X,
  BOTTOM_END_X,
};

struct position {
  int16_t x{0};
  int16_t y{0};
};

struct size {
  uint16_t w{1U};
  uint16_t h{1U};
};

struct side_values {
  uint16_t left{0U};
  uint16_t right{0U};
};

struct edge_values {
  uint16_t left{0U};
  uint16_t right{0U};
  uint16_t top{0U};
  uint16_t bottom{0U};
};

struct border_settings {
  uint32_t color{0xFF000000};
  uint16_t size{0U};
};

struct line_settings {
  uint32_t color{0xFF000000};
  uint16_t size{0U};
};

struct action {
  mousebtn button{mousebtn::NONE};
  string command{};
};

struct action_block : public action {
  alignment align{alignment::NONE};
  volatile double start_x{0.0};
  volatile double end_x{0.0};
  bool active{true};

  uint16_t width() const {
    return static_cast<uint16_t>(end_x - start_x + 0.5);
  }
};

struct bar_settings {
  explicit bar_settings() = default;
  bar_settings(const bar_settings& other) = default;

  xcb_window_t window{XCB_NONE};
  monitor_t monitor{};
  edge origin{edge::TOP};
  struct size size {
    1U, 1U
  };
  position pos{0, 0};
  position offset{0, 0};
  position center{0, 0};
  side_values padding{0U, 0U};
  side_values margin{0U, 0U};
  side_values module_margin{0U, 2U};
  edge_values strut{0U, 0U, 0U, 0U};

  uint32_t background{0xFFFFFFFF};
  uint32_t foreground{0xFF000000};

  line_settings underline{};
  line_settings overline{};

  std::unordered_map<edge, border_settings, enum_hash> borders{};

  uint8_t spacing{1U};
  string separator{};

  string wmname{};
  string locale{};

  bool override_redirect{false};

  vector<action> actions{};

  bool dimmed{false};
  double dimvalue{1.0};

  const xcb_rectangle_t inner_area(bool abspos = false) const {
    xcb_rectangle_t rect{0, 0, size.w, size.h};

    if (abspos) {
      rect.x = pos.x;
      rect.y = pos.y;
    }
    if (borders.find(edge::TOP) != borders.end()) {
      rect.y += borders.at(edge::TOP).size;
      rect.height -= borders.at(edge::TOP).size;
    }
    if (borders.find(edge::BOTTOM) != borders.end()) {
      rect.height -= borders.at(edge::BOTTOM).size;
    }
    if (borders.find(edge::LEFT) != borders.end()) {
      rect.x += borders.at(edge::LEFT).size;
      rect.width -= borders.at(edge::LEFT).size;
    }
    if (borders.find(edge::RIGHT) != borders.end()) {
      rect.width -= borders.at(edge::RIGHT).size;
    }
    return rect;
  }
};

struct event_timer {
  xcb_timestamp_t event{0L};
  xcb_timestamp_t offset{1L};

  bool allow(xcb_timestamp_t time) {
    bool pass = time >= event + offset;
    event = time;
    return pass;
  };

  bool deny(xcb_timestamp_t time) {
    return !allow(time);
  };
};

POLYBAR_NS_END
<|endoftext|>


<commit_before>#line 2 "togo/core/parser/types.hpp"
/**
@copyright MIT license; see @ref index or the accompanying LICENSE file.

@file
@brief Parser types.
@ingroup lib_core_types
@ingroup lib_core_parser
*/

#pragma once

#include <togo/core/config.hpp>
#include <togo/core/types.hpp>
#include <togo/core/utility/types.hpp>
#include <togo/core/utility/traits.hpp>
#include <togo/core/memory/types.hpp>
#include <togo/core/collection/types.hpp>
#include <togo/core/string/types.hpp>

namespace togo {
/**
	@addtogroup lib_core_parser
	@{
*/

// Forward declarations
namespace parser {

struct Parser;

} // namespace parser

namespace parse_state {

struct ParsePosition;
struct ParseState;
enum class ParseResultCode : unsigned;

} // namespace parse_state

namespace parser {

/// Parser type.
enum class ParserType : unsigned {
	Undefined,

	// intangible
	Nothing,
	Empty,
	Head,
	Tail,

	// values
	Char,
	CharRange,
	String,
	Bounded,

	// series
	Any,
	All,

	// branch
	Ref,

	// call
	Func,

	// conditional_call
	Close,
};
static constexpr unsigned const c_num_types = unsigned_cast(ParserType::Close) + 1;

/// Parser modifiers.
///
/// These are executed in order of definition.
enum class ParserModifier : unsigned {
	/// No modifiers.
	none = 0,
	/// Report no_match instead of failure.
	maybe			= 1 << 0,
	/// Suppress results.
	test			= 1 << 1,
	/// Suppress results and produce a slice for the parsed segment.
	flatten			= 1 << 2,
	/// One or more.
	repeat			= 1 << 3,
	/// Zero or more.
	repeat_or_none	= 1 << 4,
};

using PMod = ParserModifier;

/// Parse function type.
using parse_func_type = parse_state::ParseResultCode (
	Parser const* p,
	parse_state::ParseState& s,
	parse_state::ParsePosition const& from
);

/// Parser data.
template<ParserType, typename = void> struct ParserData;

#define PARSER_TRAIT_TYPE(name_) \
template<ParserType T> struct name_ { \
	static constexpr bool const value = false

PARSER_TRAIT_TYPE(is_value)
	|| T == ParserType::Char
	|| T == ParserType::CharRange
	|| T == ParserType::String
;};

PARSER_TRAIT_TYPE(is_series)
	|| T == ParserType::All
	|| T == ParserType::Any
;};

PARSER_TRAIT_TYPE(is_branch)
	|| T == ParserType::Ref
;};

PARSER_TRAIT_TYPE(is_conditional_call)
	|| T == ParserType::Close
;};

#undef PARSER_TRAIT_TYPE

/// Undefined.
using Undefined = ParserData<ParserType::Undefined>;
/// Match nothing (always succeeds).
using Nothing = ParserData<ParserType::Nothing>;
/// Match an empty input.
using Empty = ParserData<ParserType::Empty>;
/// Match the beginning of the input.
using Head = ParserData<ParserType::Head>;
/// Match the end of the input.
using Tail = ParserData<ParserType::Tail>;

/// Match a single character.
using Char = ParserData<ParserType::Char>;
/// Match a character range.
using CharRange = ParserData<ParserType::CharRange>;
/// Match a string.
using String = ParserData<ParserType::String>;
/// Match a bounded parser.
using Bounded = ParserData<ParserType::Bounded>;

/// Match any in a series.
using Any = ParserData<ParserType::Any>;
/// Match all in a series.
using All = ParserData<ParserType::All>;

/// Match another parser after modifiers.
using Ref = ParserData<ParserType::Ref>;

/// Call a parse function.
using Func = ParserData<ParserType::Func>;

/// Match a parser and call a function if it succeeds.
using Close = ParserData<ParserType::Close>;

template<> struct ParserData<ParserType::Undefined> {};
template<> struct ParserData<ParserType::Nothing> {};
template<> struct ParserData<ParserType::Empty> {};
template<> struct ParserData<ParserType::Head> {};
template<> struct ParserData<ParserType::Tail> {};

template<>
struct ParserData<ParserType::Char> {
	signed c;
};

template<>
struct ParserData<ParserType::CharRange> {
	signed b;
	signed e;
};

template<>
struct ParserData<ParserType::String> {
	StringRef s;
};

template<>
struct ParserData<ParserType::Bounded> {
	signed opener;
	signed closer;
	Parser const* p;

	ParserData(char opener, char closer, Parser const& p);
	ParserData(Allocator& a, char opener, char closer, Parser&& p);
};

template<ParserType T>
struct ParserData<T, enable_if<is_series<T>::value>> {
	unsigned num;
	Parser const** p;

	template<class... P>
	ParserData(Allocator& a, P&&... p);
};

template<ParserType T>
struct ParserData<T, enable_if<is_branch<T>::value>> {
	Parser const* p;

	ParserData(Parser const& p);
	ParserData(Allocator& a, Parser&& p);
};

template<>
struct ParserData<ParserType::Func> {
	parse_func_type* f;
	void* userdata;

	ParserData(parse_func_type* f);
	ParserData(parse_func_type* f, void* userdata);
	ParserData(void* userdata, parse_func_type* f);
};

template<ParserType T>
struct ParserData<T, enable_if<is_conditional_call<T>::value>> {
	parse_func_type* f;
	Parser const* p;

	ParserData(parse_func_type* f);
	ParserData(parse_func_type* f, Parser const& p);
	ParserData(Parser const& p, parse_func_type* f);
	ParserData(Allocator& a, parse_func_type* f, Parser&& p);
	ParserData(Allocator& a, Parser&& p, parse_func_type* f);
};

/// Parser.
struct Parser {
	// {u16 type; u16 modifiers;}
	u32 properties;
	hash32 name_hash;
	StringRef name;

	union Storage {
		Char Char;
		CharRange CharRange;
		String String;
		Bounded Bounded;

		Any Any;
		All All;

		Ref Ref;

		Func Func;

		Close Close;

		Storage(no_init_tag) {}

		Storage(parser::Undefined&&) {}
		Storage(parser::Nothing&&) {}
		Storage(parser::Empty&&) {}
		Storage(parser::Head&&) {}
		Storage(parser::Tail&&) {}

		Storage(parser::Char&& d) : Char(rvalue_ref(d)) {}
		Storage(parser::CharRange&& d) : CharRange(rvalue_ref(d)) {}
		Storage(parser::String&& d) : String(rvalue_ref(d)) {}
		Storage(parser::Bounded&& d) : Bounded(rvalue_ref(d)) {}

		Storage(parser::Any&& d) : Any(rvalue_ref(d)) {}
		Storage(parser::All&& d) : All(rvalue_ref(d)) {}

		Storage(parser::Ref&& d) : Ref(rvalue_ref(d)) {}

		Storage(parser::Func&& d) : Func(rvalue_ref(d)) {}

		Storage(parser::Close&& d) : Close(rvalue_ref(d)) {}
	} s;

	/// Construct named Undefined parser.
	Parser(StringRef name);

	/// Construct unnamed Undefined parser.
	Parser();

	/// Construct named parser with modifiers.
	template<ParserType T>
	Parser(StringRef name, ParserModifier mods, ParserData<T>&& d);

	/// Construct named parser.
	template<ParserType T>
	Parser(StringRef name, ParserData<T>&& d);

	/// Construct unnamed parser with modifiers.
	template<ParserType T>
	Parser(ParserModifier mods, ParserData<T>&& d);

	/// Construct unnamed parser.
	template<ParserType T>
	Parser(ParserData<T>&& d);
};

/// sizeof(Parser) * num.
inline constexpr unsigned sizeof_n(unsigned num = 1) {
	return sizeof(Parser) * num;
}

/// The allocation size of a series parser (e.g., Any).
inline constexpr unsigned sizeof_series(unsigned num_ref, unsigned num_inplace = 0) {
	return sizeof(Parser*) * (num_ref + num_inplace) + sizeof_n(num_inplace);
}

/// FixedAllocator helper.
template<
	unsigned num_ref,
	unsigned num_inplace = 0,
	unsigned num = 0
>
using FixedParserAllocator = FixedAllocator<0
	+ sizeof_series(num_ref, num_inplace)
	+ sizeof_n(num)
>;

/// Predefined parsers.
struct PDef {
	/// [ \t\n\r]+ :t => nothing
	static Parser const whitespace;
	/// <whitespace>? => nothing
	static Parser const whitespace_maybe;

	/// "null" => null
	static Parser const null;
	/// (true|false) => bool
	static Parser const boolean;

	/// [\-+] => char
	static Parser const sign;
	/// <sign>? => char
	static Parser const sign_maybe;

	/// [0-9] => char
	static Parser const digit_dec;
	/// <digit_dec>+ => slice
	static Parser const digits_dec;

	/// [0-9a-fA-F] => char
	static Parser const digit_hex;
	/// <digit_hex>+ => slice
	static Parser const digits_hex;

	/// [0-7] => char
	static Parser const digit_oct;
	/// <digit_oct>+ => slice
	static Parser const digits_oct;

	/// <digits> => u64
	static Parser const u64_dec;
	/// 0[xX]<hex_digits> => u64
	static Parser const u64_hex;
	/// 0<oct_digits> => u64
	static Parser const u64_oct;
	/// (<u64_dec>|<u64_hex>|<u64_oct>) => u64
	static Parser const u64_any;

	/// <sign_maybe><u64_dec> => s64
	static Parser const s64_dec;
	/// (<s64_dec>|<u64_hex>|<u64_oct>) => s64
	static Parser const s64_any;

	/// <sign_maybe><digits>\.<digits> => f64
	static Parser const f64_basic;
	/// <f64_basic>([eE]<sign_maybe><digits>)? => f64
	static Parser const f64_exp;
};

} // namespace parser

namespace parse_state {

/// Parse result code.
enum class ParseResultCode : unsigned {
	fail,
	ok,
	no_match,
};
static constexpr unsigned const c_num_result_codes = unsigned_cast(ParseResultCode::no_match) + 1;

/// Whether a result code is fail-y.
inline constexpr bool operator!(ParseResultCode rc) {
	return rc == ParseResultCode::fail;
}

/// Parse position.
struct ParsePosition {
	char const* p;
	u32_fast i;
};

struct Slice {
	char const* b;
	char const* e;
};

/// Parse result.
struct ParseResult {
	enum Type : unsigned {
		type_null,
		type_bool,
		type_char,
		type_s64,
		type_u64,
		type_f64,
		type_pointer,
		type_slice,

		type_user_base,
	};

	Type type;
	union {
		bool b;
		char c;
		s64 i;
		u64 u;
		f64 f;
		void const* p;
		Slice s;
	};

	ParseResult() = default;
	~ParseResult() = default;

	ParseResult(Type type) : type(type) {}
	ParseResult(Type type, void const* p) : type(type), p(p) {}
	ParseResult(null_tag const) : type(type_null) {}
	ParseResult(bool b) : type(type_bool), b(b) {}
	ParseResult(char c) : type(type_char), c(c) {}
	ParseResult(s32 i) : type(type_s64), i(i) {}
	ParseResult(s64 i) : type(type_s64), i(i) {}
	ParseResult(u32 u) : type(type_u64), u(u) {}
	ParseResult(u64 u) : type(type_u64), u(u) {}
	ParseResult(f32 f) : type(type_f64), f(f) {}
	ParseResult(f64 f) : type(type_f64), f(f) {}
	ParseResult(void const* p) : type(type_pointer), p(p) {}
	ParseResult(char const* b, char const* e) : type(type_slice), s{b, e} {}
};

/// Parse error.
struct ParseError {
	/// Line where the error occurred.
	unsigned line;
	/// Column where the error occurred.
	unsigned column;

	/// Result code.
	ParseResultCode result_code;
	/// Error message.
	FixedArray<char, 512> message;
};

/// Parse state.
struct ParseState {
	char const* p;
	char const* b;
	char const* e;
	char const* t;
	Array<ParseResult> results;
	unsigned suppress_results;
	unsigned suppress_errors;
	unsigned line;
	unsigned column;
	ParseError* error;
	void* userdata;

	ParseState(
		Allocator& allocator,
		ParseError* error = nullptr,
		void* userdata = nullptr
	)
		: p(nullptr)
		, b(nullptr)
		, e(nullptr)
		, t(nullptr)
		, results(allocator)
		, suppress_results(0)
		, suppress_errors(0)
		, line(0)
		, column(0)
		, error(error)
		, userdata(userdata)
	{}
};

} // namespace parse_state

/** @} */ // end of doc-group lib_core_parser

/** @cond INTERNAL */
template<> struct enable_enum_bitwise_ops<parser::ParserModifier> : true_type {};
/** @endcond */ // INTERNAL

using parser::Undefined;
using parser::Nothing;
using parser::Empty;
using parser::Head;
using parser::Tail;

using parser::Char;
using parser::CharRange;
using parser::String;
using parser::Bounded;

using parser::Any;
using parser::All;

using parser::Ref;

using parser::Func;

using parser::Close;

using parser::ParserType;
using parser::ParserModifier;
using parser::PMod;
using parser::Parser;
using parser::FixedParserAllocator;

using parse_state::ParseResultCode;
using parse_state::ParseResult;
using parse_state::ParsePosition;
using parse_state::ParseError;
using parse_state::ParseState;

using parser::PDef;

} // namespace togo
<commit_msg>lib/core/parser: PDef: corrected regex descriptions for u64_any and s64_any.<commit_after>#line 2 "togo/core/parser/types.hpp"
/**
@copyright MIT license; see @ref index or the accompanying LICENSE file.

@file
@brief Parser types.
@ingroup lib_core_types
@ingroup lib_core_parser
*/

#pragma once

#include <togo/core/config.hpp>
#include <togo/core/types.hpp>
#include <togo/core/utility/types.hpp>
#include <togo/core/utility/traits.hpp>
#include <togo/core/memory/types.hpp>
#include <togo/core/collection/types.hpp>
#include <togo/core/string/types.hpp>

namespace togo {
/**
	@addtogroup lib_core_parser
	@{
*/

// Forward declarations
namespace parser {

struct Parser;

} // namespace parser

namespace parse_state {

struct ParsePosition;
struct ParseState;
enum class ParseResultCode : unsigned;

} // namespace parse_state

namespace parser {

/// Parser type.
enum class ParserType : unsigned {
	Undefined,

	// intangible
	Nothing,
	Empty,
	Head,
	Tail,

	// values
	Char,
	CharRange,
	String,
	Bounded,

	// series
	Any,
	All,

	// branch
	Ref,

	// call
	Func,

	// conditional_call
	Close,
};
static constexpr unsigned const c_num_types = unsigned_cast(ParserType::Close) + 1;

/// Parser modifiers.
///
/// These are executed in order of definition.
enum class ParserModifier : unsigned {
	/// No modifiers.
	none = 0,
	/// Report no_match instead of failure.
	maybe			= 1 << 0,
	/// Suppress results.
	test			= 1 << 1,
	/// Suppress results and produce a slice for the parsed segment.
	flatten			= 1 << 2,
	/// One or more.
	repeat			= 1 << 3,
	/// Zero or more.
	repeat_or_none	= 1 << 4,
};

using PMod = ParserModifier;

/// Parse function type.
using parse_func_type = parse_state::ParseResultCode (
	Parser const* p,
	parse_state::ParseState& s,
	parse_state::ParsePosition const& from
);

/// Parser data.
template<ParserType, typename = void> struct ParserData;

#define PARSER_TRAIT_TYPE(name_) \
template<ParserType T> struct name_ { \
	static constexpr bool const value = false

PARSER_TRAIT_TYPE(is_value)
	|| T == ParserType::Char
	|| T == ParserType::CharRange
	|| T == ParserType::String
;};

PARSER_TRAIT_TYPE(is_series)
	|| T == ParserType::All
	|| T == ParserType::Any
;};

PARSER_TRAIT_TYPE(is_branch)
	|| T == ParserType::Ref
;};

PARSER_TRAIT_TYPE(is_conditional_call)
	|| T == ParserType::Close
;};

#undef PARSER_TRAIT_TYPE

/// Undefined.
using Undefined = ParserData<ParserType::Undefined>;
/// Match nothing (always succeeds).
using Nothing = ParserData<ParserType::Nothing>;
/// Match an empty input.
using Empty = ParserData<ParserType::Empty>;
/// Match the beginning of the input.
using Head = ParserData<ParserType::Head>;
/// Match the end of the input.
using Tail = ParserData<ParserType::Tail>;

/// Match a single character.
using Char = ParserData<ParserType::Char>;
/// Match a character range.
using CharRange = ParserData<ParserType::CharRange>;
/// Match a string.
using String = ParserData<ParserType::String>;
/// Match a bounded parser.
using Bounded = ParserData<ParserType::Bounded>;

/// Match any in a series.
using Any = ParserData<ParserType::Any>;
/// Match all in a series.
using All = ParserData<ParserType::All>;

/// Match another parser after modifiers.
using Ref = ParserData<ParserType::Ref>;

/// Call a parse function.
using Func = ParserData<ParserType::Func>;

/// Match a parser and call a function if it succeeds.
using Close = ParserData<ParserType::Close>;

template<> struct ParserData<ParserType::Undefined> {};
template<> struct ParserData<ParserType::Nothing> {};
template<> struct ParserData<ParserType::Empty> {};
template<> struct ParserData<ParserType::Head> {};
template<> struct ParserData<ParserType::Tail> {};

template<>
struct ParserData<ParserType::Char> {
	signed c;
};

template<>
struct ParserData<ParserType::CharRange> {
	signed b;
	signed e;
};

template<>
struct ParserData<ParserType::String> {
	StringRef s;
};

template<>
struct ParserData<ParserType::Bounded> {
	signed opener;
	signed closer;
	Parser const* p;

	ParserData(char opener, char closer, Parser const& p);
	ParserData(Allocator& a, char opener, char closer, Parser&& p);
};

template<ParserType T>
struct ParserData<T, enable_if<is_series<T>::value>> {
	unsigned num;
	Parser const** p;

	template<class... P>
	ParserData(Allocator& a, P&&... p);
};

template<ParserType T>
struct ParserData<T, enable_if<is_branch<T>::value>> {
	Parser const* p;

	ParserData(Parser const& p);
	ParserData(Allocator& a, Parser&& p);
};

template<>
struct ParserData<ParserType::Func> {
	parse_func_type* f;
	void* userdata;

	ParserData(parse_func_type* f);
	ParserData(parse_func_type* f, void* userdata);
	ParserData(void* userdata, parse_func_type* f);
};

template<ParserType T>
struct ParserData<T, enable_if<is_conditional_call<T>::value>> {
	parse_func_type* f;
	Parser const* p;

	ParserData(parse_func_type* f);
	ParserData(parse_func_type* f, Parser const& p);
	ParserData(Parser const& p, parse_func_type* f);
	ParserData(Allocator& a, parse_func_type* f, Parser&& p);
	ParserData(Allocator& a, Parser&& p, parse_func_type* f);
};

/// Parser.
struct Parser {
	// {u16 type; u16 modifiers;}
	u32 properties;
	hash32 name_hash;
	StringRef name;

	union Storage {
		Char Char;
		CharRange CharRange;
		String String;
		Bounded Bounded;

		Any Any;
		All All;

		Ref Ref;

		Func Func;

		Close Close;

		Storage(no_init_tag) {}

		Storage(parser::Undefined&&) {}
		Storage(parser::Nothing&&) {}
		Storage(parser::Empty&&) {}
		Storage(parser::Head&&) {}
		Storage(parser::Tail&&) {}

		Storage(parser::Char&& d) : Char(rvalue_ref(d)) {}
		Storage(parser::CharRange&& d) : CharRange(rvalue_ref(d)) {}
		Storage(parser::String&& d) : String(rvalue_ref(d)) {}
		Storage(parser::Bounded&& d) : Bounded(rvalue_ref(d)) {}

		Storage(parser::Any&& d) : Any(rvalue_ref(d)) {}
		Storage(parser::All&& d) : All(rvalue_ref(d)) {}

		Storage(parser::Ref&& d) : Ref(rvalue_ref(d)) {}

		Storage(parser::Func&& d) : Func(rvalue_ref(d)) {}

		Storage(parser::Close&& d) : Close(rvalue_ref(d)) {}
	} s;

	/// Construct named Undefined parser.
	Parser(StringRef name);

	/// Construct unnamed Undefined parser.
	Parser();

	/// Construct named parser with modifiers.
	template<ParserType T>
	Parser(StringRef name, ParserModifier mods, ParserData<T>&& d);

	/// Construct named parser.
	template<ParserType T>
	Parser(StringRef name, ParserData<T>&& d);

	/// Construct unnamed parser with modifiers.
	template<ParserType T>
	Parser(ParserModifier mods, ParserData<T>&& d);

	/// Construct unnamed parser.
	template<ParserType T>
	Parser(ParserData<T>&& d);
};

/// sizeof(Parser) * num.
inline constexpr unsigned sizeof_n(unsigned num = 1) {
	return sizeof(Parser) * num;
}

/// The allocation size of a series parser (e.g., Any).
inline constexpr unsigned sizeof_series(unsigned num_ref, unsigned num_inplace = 0) {
	return sizeof(Parser*) * (num_ref + num_inplace) + sizeof_n(num_inplace);
}

/// FixedAllocator helper.
template<
	unsigned num_ref,
	unsigned num_inplace = 0,
	unsigned num = 0
>
using FixedParserAllocator = FixedAllocator<0
	+ sizeof_series(num_ref, num_inplace)
	+ sizeof_n(num)
>;

/// Predefined parsers.
struct PDef {
	/// [ \t\n\r]+ :t => nothing
	static Parser const whitespace;
	/// <whitespace>? => nothing
	static Parser const whitespace_maybe;

	/// "null" => null
	static Parser const null;
	/// (true|false) => bool
	static Parser const boolean;

	/// [\-+] => char
	static Parser const sign;
	/// <sign>? => char
	static Parser const sign_maybe;

	/// [0-9] => char
	static Parser const digit_dec;
	/// <digit_dec>+ => slice
	static Parser const digits_dec;

	/// [0-9a-fA-F] => char
	static Parser const digit_hex;
	/// <digit_hex>+ => slice
	static Parser const digits_hex;

	/// [0-7] => char
	static Parser const digit_oct;
	/// <digit_oct>+ => slice
	static Parser const digits_oct;

	/// <digits> => u64
	static Parser const u64_dec;
	/// 0[xX]<hex_digits> => u64
	static Parser const u64_hex;
	/// 0<oct_digits> => u64
	static Parser const u64_oct;
	/// (<u64_hex>|<u64_oct>|<u64_dec>) => u64
	static Parser const u64_any;

	/// <sign_maybe><u64_dec> => s64
	static Parser const s64_dec;
	/// (<u64_hex>|<u64_oct>|<s64_dec>) => s64
	static Parser const s64_any;

	/// <sign_maybe><digits>\.<digits> => f64
	static Parser const f64_basic;
	/// <f64_basic>([eE]<sign_maybe><digits>)? => f64
	static Parser const f64_exp;
};

} // namespace parser

namespace parse_state {

/// Parse result code.
enum class ParseResultCode : unsigned {
	fail,
	ok,
	no_match,
};
static constexpr unsigned const c_num_result_codes = unsigned_cast(ParseResultCode::no_match) + 1;

/// Whether a result code is fail-y.
inline constexpr bool operator!(ParseResultCode rc) {
	return rc == ParseResultCode::fail;
}

/// Parse position.
struct ParsePosition {
	char const* p;
	u32_fast i;
};

struct Slice {
	char const* b;
	char const* e;
};

/// Parse result.
struct ParseResult {
	enum Type : unsigned {
		type_null,
		type_bool,
		type_char,
		type_s64,
		type_u64,
		type_f64,
		type_pointer,
		type_slice,

		type_user_base,
	};

	Type type;
	union {
		bool b;
		char c;
		s64 i;
		u64 u;
		f64 f;
		void const* p;
		Slice s;
	};

	ParseResult() = default;
	~ParseResult() = default;

	ParseResult(Type type) : type(type) {}
	ParseResult(Type type, void const* p) : type(type), p(p) {}
	ParseResult(null_tag const) : type(type_null) {}
	ParseResult(bool b) : type(type_bool), b(b) {}
	ParseResult(char c) : type(type_char), c(c) {}
	ParseResult(s32 i) : type(type_s64), i(i) {}
	ParseResult(s64 i) : type(type_s64), i(i) {}
	ParseResult(u32 u) : type(type_u64), u(u) {}
	ParseResult(u64 u) : type(type_u64), u(u) {}
	ParseResult(f32 f) : type(type_f64), f(f) {}
	ParseResult(f64 f) : type(type_f64), f(f) {}
	ParseResult(void const* p) : type(type_pointer), p(p) {}
	ParseResult(char const* b, char const* e) : type(type_slice), s{b, e} {}
};

/// Parse error.
struct ParseError {
	/// Line where the error occurred.
	unsigned line;
	/// Column where the error occurred.
	unsigned column;

	/// Result code.
	ParseResultCode result_code;
	/// Error message.
	FixedArray<char, 512> message;
};

/// Parse state.
struct ParseState {
	char const* p;
	char const* b;
	char const* e;
	char const* t;
	Array<ParseResult> results;
	unsigned suppress_results;
	unsigned suppress_errors;
	unsigned line;
	unsigned column;
	ParseError* error;
	void* userdata;

	ParseState(
		Allocator& allocator,
		ParseError* error = nullptr,
		void* userdata = nullptr
	)
		: p(nullptr)
		, b(nullptr)
		, e(nullptr)
		, t(nullptr)
		, results(allocator)
		, suppress_results(0)
		, suppress_errors(0)
		, line(0)
		, column(0)
		, error(error)
		, userdata(userdata)
	{}
};

} // namespace parse_state

/** @} */ // end of doc-group lib_core_parser

/** @cond INTERNAL */
template<> struct enable_enum_bitwise_ops<parser::ParserModifier> : true_type {};
/** @endcond */ // INTERNAL

using parser::Undefined;
using parser::Nothing;
using parser::Empty;
using parser::Head;
using parser::Tail;

using parser::Char;
using parser::CharRange;
using parser::String;
using parser::Bounded;

using parser::Any;
using parser::All;

using parser::Ref;

using parser::Func;

using parser::Close;

using parser::ParserType;
using parser::ParserModifier;
using parser::PMod;
using parser::Parser;
using parser::FixedParserAllocator;

using parse_state::ParseResultCode;
using parse_state::ParseResult;
using parse_state::ParsePosition;
using parse_state::ParseError;
using parse_state::ParseState;

using parser::PDef;

} // namespace togo
<|endoftext|>


<commit_before>/*
Copyright 2015 University of Auckland

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

#include <cstring>
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/xmlerror.h>
#include <string>
#include <vector>

#include "xmldoc.h"
#include "xmlnode.h"

namespace libcellml {

/**
 * @brief Callback for errors from the libxml2 context parser.
 *
 * Structured callback @c xmlStructuredErrorFunc for errors
 * from the libxml2 context parser used to parse this document.
 *
 * @param userData Private data type used to store the libxml context.
 *
 * @param error The @c xmlErrorPtr to the error raised by libxml.
 */
void structuredErrorCallback(void *userData, xmlErrorPtr error)
{
  std::string errorString = std::string(error->message);
  errorString.replace(errorString.end()-1, errorString.end(), ".");
  xmlParserCtxtPtr context = reinterpret_cast<xmlParserCtxtPtr>(userData);
  XmlDoc *doc = reinterpret_cast<XmlDoc *>(context->_private);
  doc->addXmlError(errorString);
}

/**
 * @brief The XmlDoc::XmlDocImpl struct.
 *
 * This struct is the private implementation struct for the XmlDoc class.  Separating
 * the implementation from the definition allows for greater flexibility when
 * distributing the code.
 */
struct XmlDoc::XmlDocImpl
{
    xmlDocPtr mXmlDocPtr;
    std::vector<std::string> mXmlErrors;
};

XmlDoc::XmlDoc()
    : mPimpl(new XmlDocImpl())
{
}

XmlDoc::~XmlDoc()
{
    if (mPimpl->mXmlDocPtr) {
        xmlFreeDoc(mPimpl->mXmlDocPtr);
    }
    delete mPimpl;
}

void XmlDoc::parse(const std::string& input)
{
    xmlParserCtxtPtr context = xmlNewParserCtxt();
    context->_private = reinterpret_cast<void *> (this);
    xmlSetStructuredErrorFunc(context, structuredErrorCallback);
    mPimpl->mXmlDocPtr = xmlCtxtReadDoc(context, BAD_CAST input.c_str(),"/", NULL, 0);
    xmlFreeParserCtxt(context);
}

XmlNodePtr XmlDoc::getRootNode() const
{
    if (mPimpl->mXmlDocPtr == nullptr) {
        throw std::invalid_argument("No valid XML Document found.");
    }
    xmlNodePtr root = xmlDocGetRootElement(mPimpl->mXmlDocPtr);
    XmlNodePtr rootHandle = std::make_shared<XmlNode>();
    rootHandle->setXmlNode(root);
    return rootHandle;
}

void XmlDoc::addXmlError(const std::string error)
{
    mPimpl->mXmlErrors.push_back(error);
}

size_t XmlDoc::xmlErrorCount() const
{
    return mPimpl->mXmlErrors.size();
}

std::string XmlDoc::getXmlError(size_t index) const
{
    return mPimpl->mXmlErrors.at(index);
}

}
<commit_msg>check that libxml error ends in newline before replacing with a period<commit_after>/*
Copyright 2015 University of Auckland

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

#include <cstring>
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/xmlerror.h>
#include <string>
#include <vector>

#include "xmldoc.h"
#include "xmlnode.h"

namespace libcellml {

/**
 * @brief Callback for errors from the libxml2 context parser.
 *
 * Structured callback @c xmlStructuredErrorFunc for errors
 * from the libxml2 context parser used to parse this document.
 *
 * @param userData Private data type used to store the libxml context.
 *
 * @param error The @c xmlErrorPtr to the error raised by libxml.
 */
void structuredErrorCallback(void *userData, xmlErrorPtr error)
{
  std::string errorString = std::string(error->message);
  // Swap libxml2 carriage return for a period.
  if (errorString.substr(errorString.length() - 1) == "\n") {
      errorString.replace(errorString.end()-1, errorString.end(), ".");
  }
  xmlParserCtxtPtr context = reinterpret_cast<xmlParserCtxtPtr>(userData);
  XmlDoc *doc = reinterpret_cast<XmlDoc *>(context->_private);
  doc->addXmlError(errorString);
}

/**
 * @brief The XmlDoc::XmlDocImpl struct.
 *
 * This struct is the private implementation struct for the XmlDoc class.  Separating
 * the implementation from the definition allows for greater flexibility when
 * distributing the code.
 */
struct XmlDoc::XmlDocImpl
{
    xmlDocPtr mXmlDocPtr;
    std::vector<std::string> mXmlErrors;
};

XmlDoc::XmlDoc()
    : mPimpl(new XmlDocImpl())
{
}

XmlDoc::~XmlDoc()
{
    if (mPimpl->mXmlDocPtr) {
        xmlFreeDoc(mPimpl->mXmlDocPtr);
    }
    delete mPimpl;
}

void XmlDoc::parse(const std::string& input)
{
    xmlParserCtxtPtr context = xmlNewParserCtxt();
    context->_private = reinterpret_cast<void *> (this);
    xmlSetStructuredErrorFunc(context, structuredErrorCallback);
    mPimpl->mXmlDocPtr = xmlCtxtReadDoc(context, BAD_CAST input.c_str(),"/", NULL, 0);
    xmlFreeParserCtxt(context);
}

XmlNodePtr XmlDoc::getRootNode() const
{
    if (mPimpl->mXmlDocPtr == nullptr) {
        throw std::invalid_argument("No valid XML Document found.");
    }
    xmlNodePtr root = xmlDocGetRootElement(mPimpl->mXmlDocPtr);
    XmlNodePtr rootHandle = std::make_shared<XmlNode>();
    rootHandle->setXmlNode(root);
    return rootHandle;
}

void XmlDoc::addXmlError(const std::string error)
{
    mPimpl->mXmlErrors.push_back(error);
}

size_t XmlDoc::xmlErrorCount() const
{
    return mPimpl->mXmlErrors.size();
}

std::string XmlDoc::getXmlError(size_t index) const
{
    return mPimpl->mXmlErrors.at(index);
}

}
<|endoftext|>


<commit_before>/*

Copyright (c) 2003, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef TORRENT_DEBUG_HPP_INCLUDED
#define TORRENT_DEBUG_HPP_INCLUDED

#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING

#include <string>
#include "libtorrent/config.hpp"
#include "libtorrent/file.hpp"
#include "libtorrent/thread.hpp"

#if TORRENT_USE_IOSTREAM
#include <fstream>
#include <iostream>
#endif

namespace libtorrent
{
	// DEBUG API

	struct logger
	{
#if TORRENT_USE_IOSTREAM
		// all log streams share a single file descriptor
		// and re-opens the file for each log line
		// these members are defined in session_impl.cpp
		static std::ofstream log_file;
		static std::string open_filename;
		static mutex file_mutex;
#endif

		logger(std::string const& logpath, std::string const& filename
			, int instance, bool append)
		{
			char log_name[512];
			snprintf(log_name, sizeof(log_name), "libtorrent_logs%d", instance);
			std::string dir(complete(combine_path(logpath, log_name)));
			error_code ec;
			if (!exists(dir)) create_directories(dir, ec);
			m_filename = combine_path(dir, filename);
			m_truncate = !append;
			*this << "\n\n\n*** starting log ***\n";
		}

#if TORRENT_USE_IOSTREAM
		void open()
		{
			if (open_filename == m_filename) return;
			log_file.close();
			log_file.clear();
			log_file.open(m_filename.c_str(), m_truncate ? std::ios_base::trunc : std::ios_base::app);
			open_filename = m_filename;
			m_truncate = false;
			if (!log_file.good())
				fprintf(stderr, "Failed to open logfile %s: %s\n", m_filename.c_str(), strerror(errno));
		}
#endif

		template <class T>
		logger& operator<<(T const& v)
		{
#if TORRENT_USE_IOSTREAM
			mutex::scoped_lock l(file_mutex);
			open();
			log_file << v;
			log_file.flush();
#endif
			return *this;
		}

		std::string m_filename;
		bool m_truncate;
	};

}

#endif // TORRENT_VERBOSE_LOGGING || TORRENT_LOGGING || TORRENT_ERROR_LOGGING
#endif // TORRENT_DEBUG_HPP_INCLUDED

<commit_msg>don't flush every string printed to the log<commit_after>/*

Copyright (c) 2003, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef TORRENT_DEBUG_HPP_INCLUDED
#define TORRENT_DEBUG_HPP_INCLUDED

#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING

#include <string>
#include "libtorrent/config.hpp"
#include "libtorrent/file.hpp"
#include "libtorrent/thread.hpp"

#if TORRENT_USE_IOSTREAM
#include <fstream>
#include <iostream>
#endif

namespace libtorrent
{
	// DEBUG API

	struct logger
	{
#if TORRENT_USE_IOSTREAM
		// all log streams share a single file descriptor
		// and re-opens the file for each log line
		// these members are defined in session_impl.cpp
		static std::ofstream log_file;
		static std::string open_filename;
		static mutex file_mutex;
#endif

		logger(std::string const& logpath, std::string const& filename
			, int instance, bool append)
		{
			char log_name[512];
			snprintf(log_name, sizeof(log_name), "libtorrent_logs%d", instance);
			std::string dir(complete(combine_path(logpath, log_name)));
			error_code ec;
			if (!exists(dir)) create_directories(dir, ec);
			m_filename = combine_path(dir, filename);
			m_truncate = !append;
			*this << "\n\n\n*** starting log ***\n";
		}

#if TORRENT_USE_IOSTREAM
		void open()
		{
			if (open_filename == m_filename) return;
			log_file.close();
			log_file.clear();
			log_file.open(m_filename.c_str(), m_truncate ? std::ios_base::trunc : std::ios_base::app);
			open_filename = m_filename;
			m_truncate = false;
			if (!log_file.good())
				fprintf(stderr, "Failed to open logfile %s: %s\n", m_filename.c_str(), strerror(errno));
		}
#endif

		template <class T>
		logger& operator<<(T const& v)
		{
#if TORRENT_USE_IOSTREAM
			mutex::scoped_lock l(file_mutex);
			open();
			log_file << v;
#endif
			return *this;
		}

		std::string m_filename;
		bool m_truncate;
	};

}

#endif // TORRENT_VERBOSE_LOGGING || TORRENT_LOGGING || TORRENT_ERROR_LOGGING
#endif // TORRENT_DEBUG_HPP_INCLUDED

<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2011 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef CHAR_INFO_HPP
#define CHAR_INFO_HPP

#include <boost/shared_ptr.hpp>

namespace mapnik {
struct char_properties;

class char_info {
public:
    char_info(unsigned c_, double width_, double ymax_, double ymin_, double line_height_)
        :  c(c_), width(width_), line_height(line_height_), ymin(ymin_), ymax(ymax_)
    {
    }
    char_info()
        : c(0), width(0), line_height(0), ymin(0), ymax(0)
    {
    }

    unsigned c;
    double width;
    double line_height;
    double ymin;
    double ymax;
    double avg_height;
    char_properties *format;
    double height() const { return ymax-ymin; }
};
}
#endif
<commit_msg>initialize members of char_info - refs #1114<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2011 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef CHAR_INFO_HPP
#define CHAR_INFO_HPP

#include <boost/shared_ptr.hpp>

namespace mapnik {
struct char_properties;

class char_info {
public:
    char_info(unsigned c_, double width_, double ymax_, double ymin_, double line_height_)
        :  c(c_),
           width(width_),
           line_height(line_height_),
           ymin(ymin_),
           ymax(ymax_),
           avg_height(ymax_-ymin_),
           format()
    {
    }

    char_info()
        :  c(0),
           width(0),
           line_height(0),
           ymin(0),
           ymax(0),
           avg_height(0),
           format()
    {
    }

    unsigned c;
    double width;
    double line_height;
    double ymin;
    double ymax;
    double avg_height;
    char_properties *format;
    double height() const { return ymax-ymin; }
};
}
#endif
<|endoftext|>


<commit_before>#pragma once
#include <glad/glad.h>
#include <optional>
#include <initializer_list>
#include <unordered_map>
#include <array>
#include <future>
#include <mos/gfx/scene.hpp>
#include <mos/gfx/texture_2d.hpp>
#include <mos/gfx/texture_cube.hpp>
#include <mos/gfx/model.hpp>
#include <mos/gfx/text.hpp>
#include <mos/gfx/particle_cloud.hpp>
#include <mos/gfx/light.hpp>
#include <mos/gfx/target.hpp>
#include <mos/gfx/camera.hpp>
#include <mos/gfx/environment_light.hpp>
#include <mos/gfx/fog.hpp>
#include <mos/gfx/box.hpp>

namespace mos {
namespace gfx {

/** Render geometry/models with OpenGL. */
class Renderer final {
public:
  /** Inits the renderer, creates an OpenGL context with GLEW. */
  Renderer(const glm::vec4 &color, const glm::ivec2 &resolution);

  ~Renderer();

  /** Loads a model into renderers own memory. */
  void load(const Model &model);
  void load_async(const Model &model);

  void load(const Scene::Models & models);
  void load_async(const Scene::Models &models);

  /** Unloads a model from renderers own memory. */
  void unload(const Model &model);

  /** Load a mesh in to memory. */
  void load(const Mesh &mesh);
  void load(const SharedMesh &mesh);

  /** Unloads a mesh from memory. */
  void unload(const Mesh &mesh);
  void unload(const SharedMesh &mesh);

  /** Loads a shared texture into renderer memory. */
  void load(const SharedTexture2D &texture);

  /** Loads a shared texture into render memory, async. */
  void load_async(const SharedTexture2D &texture);

  /** Loads a texture into renderer memory. */
  void load_or_update(const Texture2D &texture);

  /** Unloads a shared texture from renderer memory. */
  void unload(const SharedTexture2D &texture);

  /** Unloads a shared texture cube from renderer memory.*/
  void unload(const SharedTextureCube &texture);

  void render(const std::initializer_list<Scene> &scenes_init,
              const glm::vec4 &color = glm::vec4(.0f),
              const glm::ivec2 &resolution = glm::ivec2(128, 128));

  void render_async(const std::initializer_list<Scene> &scenes_init,
              const glm::vec4 &color = glm::vec4(.0f),
              const glm::ivec2 &resolution = glm::ivec2(128, 128));

  template<class It>
  void render(It scenes_begin,
              It scenes_end,
              const glm::vec4 &color = {.0f, .0f, .0f, 1.0f},
              const glm::ivec2 &resolution = glm::ivec2(128, 128)) {
    clear(color);
    for (auto it = scenes_begin; it != scenes_end; it++) {
      load(it->models);
      render_shadow_map(it->models, it->light);
      render_environment(*it, color);
      render_texture_targets(*it);
    }
    glBindFramebuffer(GL_FRAMEBUFFER, multi_fbo_);
    clear(color);
    for (auto it = scenes_begin; it != scenes_end; it++) {
      render_scene(it->camera, *it, resolution);
    }

    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    clear(color);

    //RenderQuad
    glUseProgram(quad_program_.program);

    glBindVertexArray(quad_vao_);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, multi_texture_);
    glUniform1i(quad_program_.quad_texture, 0);
    glDrawArrays(GL_TRIANGLES, 0, 6);
  }

  template<class It>
  void render_async(It scenes_begin,
              It scenes_end,
              const glm::vec4 &color = {.0f, .0f, .0f, 1.0f},
              const glm::ivec2 &resolution = glm::ivec2(128, 128)) {
    clear(color);
    for (auto it = scenes_begin; it != scenes_end; it++) {
      load_async(it->models);
      render_shadow_map(it->models, it->light);
      //render_environment(*it, color);
      render_scene(it->camera, *it, resolution);
    }
  }

  /** Clear all internal buffers/memory. */
  void clear_buffers();

private:
  void * ptr_;
  GLuint buffer_id_;

  GLuint multi_fbo_;
  GLuint multi_texture_;
  GLuint multi_depth_texture_;
  GLuint quad_vao_;
  GLuint quad_vbo_;

  struct Buffer {
    GLuint id; // TODO const?
    std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> modified;
  };

  struct PixelBuffer {
    GLuint id;
    std::future<void> future;
  };

  /** Uniforms for the particle shader program. */
  struct ParticleProgram {
    GLuint program;
    GLint mvp;
    GLint mv;
    GLint p;
    GLint texture;
    GLint resolution;
  };

  /** Uniforms for the bounding box shader program. */
  struct BoxProgram {
    GLuint program;
    GLint mvp;
    GLint mv;
  };

  struct QuadProgram {
    GLuint program;
    GLint quad_texture;
  };

  struct DepthProgram {
    GLuint program;
    GLint model_view_projection_matrix;
  };

  /** Uniforms for the standard shader. */
  class StandardProgram {
  public:
    //TODO make all const
    StandardProgram() {};
    StandardProgram(const GLuint program);
    GLuint program;
    GLint model_view_projection_matrix;
    GLint model_view_matrix;
    GLint model_matrix;
    GLint view_matrix;
    GLint normal_matrix;
    GLint depth_bias_mvp;

    GLint environment_map;
    GLint environment_position;
    GLint environment_extent;
    GLint environment_strength;

    GLint material_albedo_map;
    GLint material_emission_map;
    GLint material_normal_map;
    GLint material_metallic_map;
    GLint material_roughness_map;
    GLint material_ambient_occlusion_map;
    GLint material_albedo;
    GLint material_roughness;
    GLint material_metallic;
    GLint material_opacity;
    GLint material_emission;
    GLint material_ambient_occlusion;

    GLint camera_resolution;
    GLint camera_position;

    GLint light_position;
    GLint light_color;
    GLint light_view;
    GLint light_projection;
    GLint light_shadow_map;
    GLint light_angle;
    GLint light_direction;

    GLint fog_color_near;
    GLint fog_color_far;
    GLint fog_attenuation_factor;

    GLint brdf_lut;
  };

  void render_texture_targets(const Scene &scene);

  void render_scene(const Camera &camera, const Scene &render_scene, const glm::vec2 &resolution);

  void render_shadow_map(const std::vector<Model> &models, const Light &light);

  void render_environment(const Scene &render_scene, const glm::vec4 &clear_color);

  void render_boxes(const Scene::Boxes & boxes, const mos::gfx::Camera &camera);
  void render_particles(const Scene::ParticleClouds &clouds, const mos::gfx::Camera &camera, const glm::vec2 &resolution);

  void render_model(const Model &model,
                    const glm::mat4 &transform,
                    const Camera &camera,
                    const Light &light,
                    const EnvironmentLight &environment,
                    const Fog &fog,
                    const glm::vec2 &resolution,
                    const StandardProgram& program,
                    const Scene::Draw &draw);

  void render_model_depth(const Model &model,
                          const glm::mat4 &transform,
                          const Camera &camera,
                          const glm::vec2 &resolution,
                          const DepthProgram& program);

  /** Clear color and depth. */
  void clear(const glm::vec4 &color);

  unsigned int create_texture(const SharedTexture2D &texture);
  unsigned int create_texture(const Texture2D &texture);
  unsigned int create_texture_cube(const TextureCube &texture);

  unsigned int create_shader(const std::string &source,
                             const unsigned int type, const std::string& name = "");
  bool check_shader(const unsigned int shader, const std::string &name = "");
  bool check_program(const unsigned int program, const std::string &name);
  void link_program(const GLuint program,
                    const std::string& name);

  void create_box_program();
  void create_standard_program();
  void create_particle_program();
  void create_depth_program();
  void create_quad_program();

  StandardProgram standard_program_;
  ParticleProgram particle_program_;
  BoxProgram box_program_;
  DepthProgram depth_program_;
  QuadProgram quad_program_;

  std::unordered_map<unsigned int, GLuint> frame_buffers_;
  std::unordered_map<unsigned int, GLuint> render_buffers;
  std::unordered_map<unsigned int, GLuint> pixel_buffers_;
  std::unordered_map<unsigned int, Buffer> textures_;
  std::unordered_map<unsigned int, GLuint> texture_cubes_;
  std::unordered_map<unsigned int, Buffer> array_buffers_;
  std::unordered_map<unsigned int, Buffer> element_array_buffers_;
  std::unordered_map<unsigned int, GLuint> vertex_arrays_;
  std::unordered_map<unsigned int, PixelBuffer> test_buffers_;

  GLuint black_texture_;
  GLuint white_texture_;
  GLuint brdf_lut_texture_;
  GLuint box_vbo;
  GLuint box_ebo;
  GLuint box_va;

  struct FormatPair {
    GLuint internal_format;
    GLuint format;
  };
  //TODO: Static though, be aware initialization problem.
  std::map<Texture::Wrap, GLuint> wrap_map_;
  std::map<Texture::Format, FormatPair> format_map_;
  std::map<Scene::Draw, GLuint> draw_map_;

  int cube_camera_index_;
};
}
}<commit_msg>Static method<commit_after>#pragma once
#include <glad/glad.h>
#include <optional>
#include <initializer_list>
#include <unordered_map>
#include <array>
#include <future>
#include <mos/gfx/scene.hpp>
#include <mos/gfx/texture_2d.hpp>
#include <mos/gfx/texture_cube.hpp>
#include <mos/gfx/model.hpp>
#include <mos/gfx/text.hpp>
#include <mos/gfx/particle_cloud.hpp>
#include <mos/gfx/light.hpp>
#include <mos/gfx/target.hpp>
#include <mos/gfx/camera.hpp>
#include <mos/gfx/environment_light.hpp>
#include <mos/gfx/fog.hpp>
#include <mos/gfx/box.hpp>

namespace mos {
namespace gfx {

/** Render geometry/models with OpenGL. */
class Renderer final {
public:
  /** Inits the renderer, creates an OpenGL context with GLEW. */
  Renderer(const glm::vec4 &color, const glm::ivec2 &resolution);

  ~Renderer();

  /** Loads a model into renderers own memory. */
  void load(const Model &model);
  void load_async(const Model &model);

  void load(const Scene::Models & models);
  void load_async(const Scene::Models &models);

  /** Unloads a model from renderers own memory. */
  void unload(const Model &model);

  /** Load a mesh in to memory. */
  void load(const Mesh &mesh);
  void load(const SharedMesh &mesh);

  /** Unloads a mesh from memory. */
  void unload(const Mesh &mesh);
  void unload(const SharedMesh &mesh);

  /** Loads a shared texture into renderer memory. */
  void load(const SharedTexture2D &texture);

  /** Loads a shared texture into render memory, async. */
  void load_async(const SharedTexture2D &texture);

  /** Loads a texture into renderer memory. */
  void load_or_update(const Texture2D &texture);

  /** Unloads a shared texture from renderer memory. */
  void unload(const SharedTexture2D &texture);

  /** Unloads a shared texture cube from renderer memory.*/
  void unload(const SharedTextureCube &texture);

  void render(const std::initializer_list<Scene> &scenes_init,
              const glm::vec4 &color = glm::vec4(.0f),
              const glm::ivec2 &resolution = glm::ivec2(128, 128));

  void render_async(const std::initializer_list<Scene> &scenes_init,
              const glm::vec4 &color = glm::vec4(.0f),
              const glm::ivec2 &resolution = glm::ivec2(128, 128));

  template<class It>
  void render(It scenes_begin,
              It scenes_end,
              const glm::vec4 &color = {.0f, .0f, .0f, 1.0f},
              const glm::ivec2 &resolution = glm::ivec2(128, 128)) {
    clear(color);
    for (auto it = scenes_begin; it != scenes_end; it++) {
      load(it->models);
      render_shadow_map(it->models, it->light);
      render_environment(*it, color);
      render_texture_targets(*it);
    }
    glBindFramebuffer(GL_FRAMEBUFFER, multi_fbo_);
    clear(color);
    for (auto it = scenes_begin; it != scenes_end; it++) {
      render_scene(it->camera, *it, resolution);
    }

    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    clear(color);

    //RenderQuad
    glUseProgram(quad_program_.program);

    glBindVertexArray(quad_vao_);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, multi_texture_);
    glUniform1i(quad_program_.quad_texture, 0);
    glDrawArrays(GL_TRIANGLES, 0, 6);
  }

  template<class It>
  void render_async(It scenes_begin,
              It scenes_end,
              const glm::vec4 &color = {.0f, .0f, .0f, 1.0f},
              const glm::ivec2 &resolution = glm::ivec2(128, 128)) {
    clear(color);
    for (auto it = scenes_begin; it != scenes_end; it++) {
      load_async(it->models);
      render_shadow_map(it->models, it->light);
      //render_environment(*it, color);
      render_scene(it->camera, *it, resolution);
    }
  }

  /** Clear all internal buffers/memory. */
  void clear_buffers();

private:
  void * ptr_;
  GLuint buffer_id_;

  GLuint multi_fbo_;
  GLuint multi_texture_;
  GLuint multi_depth_texture_;
  GLuint quad_vao_;
  GLuint quad_vbo_;

  struct Buffer {
    GLuint id; // TODO const?
    std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> modified;
  };

  struct PixelBuffer {
    GLuint id;
    std::future<void> future;
  };

  /** Uniforms for the particle shader program. */
  struct ParticleProgram {
    GLuint program;
    GLint mvp;
    GLint mv;
    GLint p;
    GLint texture;
    GLint resolution;
  };

  /** Uniforms for the bounding box shader program. */
  struct BoxProgram {
    GLuint program;
    GLint mvp;
    GLint mv;
  };

  struct QuadProgram {
    GLuint program;
    GLint quad_texture;
  };

  struct DepthProgram {
    GLuint program;
    GLint model_view_projection_matrix;
  };

  /** Uniforms for the standard shader. */
  class StandardProgram {
  public:
    //TODO make all const
    StandardProgram() {};
    StandardProgram(const GLuint program);
    GLuint program;
    GLint model_view_projection_matrix;
    GLint model_view_matrix;
    GLint model_matrix;
    GLint view_matrix;
    GLint normal_matrix;
    GLint depth_bias_mvp;

    GLint environment_map;
    GLint environment_position;
    GLint environment_extent;
    GLint environment_strength;

    GLint material_albedo_map;
    GLint material_emission_map;
    GLint material_normal_map;
    GLint material_metallic_map;
    GLint material_roughness_map;
    GLint material_ambient_occlusion_map;
    GLint material_albedo;
    GLint material_roughness;
    GLint material_metallic;
    GLint material_opacity;
    GLint material_emission;
    GLint material_ambient_occlusion;

    GLint camera_resolution;
    GLint camera_position;

    GLint light_position;
    GLint light_color;
    GLint light_view;
    GLint light_projection;
    GLint light_shadow_map;
    GLint light_angle;
    GLint light_direction;

    GLint fog_color_near;
    GLint fog_color_far;
    GLint fog_attenuation_factor;

    GLint brdf_lut;
  };

  void render_texture_targets(const Scene &scene);

  void render_scene(const Camera &camera, const Scene &render_scene, const glm::vec2 &resolution);

  void render_shadow_map(const std::vector<Model> &models, const Light &light);

  void render_environment(const Scene &render_scene, const glm::vec4 &clear_color);

  void render_boxes(const Scene::Boxes & boxes, const mos::gfx::Camera &camera);
  void render_particles(const Scene::ParticleClouds &clouds, const mos::gfx::Camera &camera, const glm::vec2 &resolution);

  void render_model(const Model &model,
                    const glm::mat4 &transform,
                    const Camera &camera,
                    const Light &light,
                    const EnvironmentLight &environment,
                    const Fog &fog,
                    const glm::vec2 &resolution,
                    const StandardProgram& program,
                    const Scene::Draw &draw);

  void render_model_depth(const Model &model,
                          const glm::mat4 &transform,
                          const Camera &camera,
                          const glm::vec2 &resolution,
                          const DepthProgram& program);

  /** Clear color and depth. */
  void clear(const glm::vec4 &color);

  unsigned int create_texture(const SharedTexture2D &texture);
  unsigned int create_texture(const Texture2D &texture);
  unsigned int create_texture_cube(const TextureCube &texture);

  static unsigned int create_shader(const std::string &source,
                             const unsigned int type, const std::string& name = "");
  static bool check_shader(const unsigned int shader, const std::string &name = "");
  static bool check_program(const unsigned int program, const std::string &name);
  static void link_program(const GLuint program,
                    const std::string& name);

  void create_box_program();
  void create_standard_program();
  void create_particle_program();
  void create_depth_program();
  void create_quad_program();

  StandardProgram standard_program_;
  ParticleProgram particle_program_;
  BoxProgram box_program_;
  DepthProgram depth_program_;
  QuadProgram quad_program_;

  std::unordered_map<unsigned int, GLuint> frame_buffers_;
  std::unordered_map<unsigned int, GLuint> render_buffers;
  std::unordered_map<unsigned int, GLuint> pixel_buffers_;
  std::unordered_map<unsigned int, Buffer> textures_;
  std::unordered_map<unsigned int, GLuint> texture_cubes_;
  std::unordered_map<unsigned int, Buffer> array_buffers_;
  std::unordered_map<unsigned int, Buffer> element_array_buffers_;
  std::unordered_map<unsigned int, GLuint> vertex_arrays_;
  std::unordered_map<unsigned int, PixelBuffer> test_buffers_;

  GLuint black_texture_;
  GLuint white_texture_;
  GLuint brdf_lut_texture_;
  GLuint box_vbo;
  GLuint box_ebo;
  GLuint box_va;

  struct FormatPair {
    GLuint internal_format;
    GLuint format;
  };
  //TODO: Static though, be aware initialization problem.
  std::map<Texture::Wrap, GLuint> wrap_map_;
  std::map<Texture::Format, FormatPair> format_map_;
  std::map<Scene::Draw, GLuint> draw_map_;

  int cube_camera_index_;
};
}
}<|endoftext|>


<commit_before>#pragma once
#include <glad/glad.h>
#include <optional>
#include <initializer_list>
#include <unordered_map>
#include <array>
#include <future>
#include <mos/gfx/scene.hpp>
#include <mos/gfx/texture_2d.hpp>
#include <mos/gfx/model.hpp>
#include <mos/gfx/text.hpp>
#include <mos/gfx/particle_cloud.hpp>
#include <mos/gfx/light.hpp>
#include <mos/gfx/target.hpp>
#include <mos/gfx/camera.hpp>
#include <mos/gfx/environment_light.hpp>
#include <mos/gfx/fog.hpp>
#include <mos/gfx/box.hpp>
#include <mos/gfx/scenes.hpp>
#include <mos/gfx/lights.hpp>

namespace mos {
namespace gfx {

/** Render geometry/models with OpenGL. */
class Renderer final {
public:
  /** Inits the renderer, creates an OpenGL context with GLEW. */
  Renderer(const glm::vec4 &color, const glm::ivec2 &resolution);

  ~Renderer();

  /** Loads a model into renderers own memory. */
  void load(const Model &model);

  void load(const Models & models);

  /** Unloads a model from renderers own memory. */
  void unload(const Model &model);

  /** Load a mesh in to memory. */
  void load(const Mesh &mesh);
  void load(const SharedMesh &mesh);

  /** Unloads a mesh from memory. */
  void unload(const Mesh &mesh);
  void unload(const SharedMesh &mesh);

  /** Loads a shared texture into renderer memory. */
  void load(const SharedTexture2D &texture);

  /** Loads a texture into renderer memory. */
  void load_or_update(const Texture2D &texture);

  /** Unloads a shared texture from renderer memory. */
  void unload(const SharedTexture2D &texture);

  /** Render multiple scenes. */
  void render(const Scenes &scenes,
              const glm::vec4 &color = {.0f, .0f, .0f, 1.0f},
              const glm::ivec2 &resolution = glm::ivec2(128, 128));

  /** Clear all internal buffers/memory. */
  void clear_buffers();

private:
  using TimePoint =  std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds>;

  struct Buffer {
    GLuint id;
    TimePoint modified;
  };

  class TextureBuffer2D {
  public:
    explicit TextureBuffer2D(const Texture2D &texture_2d);
    TextureBuffer2D(const GLuint internal_format,
                    const GLuint external_format,
                    const int width,
                    const int height,
                    const GLuint wrap,
                    const void *data,
                    const bool mipmaps,
                    const TimePoint &modified = std::chrono::system_clock::now());
    ~TextureBuffer2D();
    GLuint texture;
    TimePoint modified;
  };

  class Shader {
  public:
    Shader(const std::string &source, const GLuint type, const std::string& name);
    ~Shader();
    GLuint id;
  };

  struct Program {
    Program();
    ~Program();
    GLuint program;
  };

  /** Uniforms for the particle shader program. */
  struct ParticleProgram {
    ParticleProgram();
    ~ParticleProgram();
    GLuint program;
    GLint mvp;
    GLint mv;
    GLint p;
    GLint texture;
    GLint resolution;
  };

  /** Uniforms for the bounding box shader program. */
  struct BoxProgram {
    BoxProgram();
    ~BoxProgram();
    GLuint program;
    GLint mvp;
  };

  struct MultisampleProgram {
    MultisampleProgram();
    ~MultisampleProgram();
    GLuint program;
    GLint color_texture;
    GLint depth_texture;
  };

  struct BloomProgram {
    BloomProgram();
    ~BloomProgram();
    GLuint program;
    GLint color_texture;
    GLint bright_color_texture;
    GLint strength;
  };

  struct BlurProgram {
    BlurProgram();
    ~BlurProgram();
    GLuint program;
    GLint color_texture;
    GLint horizontal;
  };

  struct DepthProgram {
    DepthProgram();
    ~DepthProgram();
    GLuint program;
    GLint model_view_projection_matrix;
  };

  /** Uniforms for the standard shader. */
  class StandardProgram {
  public:
    StandardProgram();
    ~StandardProgram();
    GLuint program;
    GLint model_view_projection_matrix;
    GLint model_matrix;
    GLint normal_matrix;
    std::array<GLint,2> depth_bias_mvps;

    struct EnvironmentUniforms{
      GLint map;
      GLint position;
      GLint extent;
      GLint strength;
    };
    std::array<EnvironmentUniforms, 2> environment_maps;

    GLint material_albedo_map;
    GLint material_emission_map;
    GLint material_normal_map;
    GLint material_metallic_map;
    GLint material_roughness_map;
    GLint material_ambient_occlusion_map;
    GLint material_albedo;
    GLint material_roughness;
    GLint material_metallic;
    GLint material_opacity;
    GLint material_emission;
    GLint material_ambient_occlusion;
    GLint material_emission_strength;
    GLint material_factor;

    GLint camera_resolution;
    GLint camera_position;

    struct LightUniforms {
      GLint position;
      GLint color;
      GLint view;
      GLint projection;
      GLint angle;
      GLint direction;
    };

    std::array<GLuint, 2> shadow_maps;
    std::array<LightUniforms, 2> lights;

    GLint fog_color_near;
    GLint fog_color_far;
    GLint fog_attenuation_factor;

    GLint brdf_lut;
  };

  void render_texture_targets(const Scene &scene);

  void render_scene(const Camera &camera,
                    const Scene &scene,
                    const glm::vec2 &resolution);

  void render_shadow_maps(const Models &models,
                          const Lights &lights);

  void render_environment(const Scene &scene,
                          const glm::vec4 &clear_color);

  void render_boxes(const Boxes & boxes,
                    const mos::gfx::Camera &camera);

  void render_particles(const ParticleClouds &clouds,
                        const mos::gfx::Camera &camera,
                        const glm::vec2 &resolution);

  void render_model(const Model &model,
                    const glm::mat4 &transform,
                    const Camera &camera,
                    const Lights &lights,
                    const EnvironmentLights &environment_lights,
                    const Fog &fog,
                    const glm::vec2 &resolution,
                    const StandardProgram& program);

  void render_model_depth(const Model &model,
                          const glm::mat4 &transform,
                          const Camera &camera,
                          const glm::vec2 &resolution,
                          const DepthProgram& program);

  /** Clear color and depth. */
  void clear(const glm::vec4 &color);
  void clear_depth();
  void clear_color(const glm::vec4 &color);

  static bool check_program(const unsigned int program,
                            const std::string &name);

  static void link_program(const GLuint program,
                    const std::string& name);

  const StandardProgram standard_program_;
  const ParticleProgram particle_program_;
  const BoxProgram box_program_;
  const DepthProgram depth_program_;
  const MultisampleProgram multisample_program_;
  const BloomProgram bloom_program_;
  const BlurProgram blur_program_;

  std::unordered_map<unsigned int, GLuint> frame_buffers_;
  std::unordered_map<unsigned int, GLuint> render_buffers;
  std::unordered_map<unsigned int, GLuint> pixel_buffers_;
  std::unordered_map<unsigned int, std::unique_ptr<TextureBuffer2D>> textures_;
  std::unordered_map<unsigned int, Buffer> array_buffers_;
  std::unordered_map<unsigned int, Buffer> element_array_buffers_;
  std::unordered_map<unsigned int, GLuint> vertex_arrays_;

  struct StandardTarget{
    StandardTarget(const glm::vec2 &resolution);
    ~StandardTarget();
    GLuint frame_buffer;
    GLuint texture;
    GLuint depth_texture;
  };

  const StandardTarget standard_target_;

  struct MultiTarget {
    MultiTarget(const glm::vec2 &resolution);
    ~MultiTarget();
    GLuint frame_buffer;
    GLuint color_texture;
    GLuint bright_texture;
  };

  const MultiTarget multi_target_;

  struct BlurTarget {
    BlurTarget(const glm::vec2 &resolution);
    ~BlurTarget();
    GLuint frame_buffer;
    GLuint texture;
  };

  const BlurTarget blur_target0_;
  const BlurTarget blur_target1_;

  struct Quad {
    Quad();
    ~Quad();
    GLuint vertex_array;
    GLuint buffer;
  };

  const Quad quad_;

  struct Box {
    Box();
    ~Box();
    GLuint buffer;
    GLuint element_buffer;
    GLuint vertex_array;
  };

  const Box box;

  const TextureBuffer2D black_texture_;
  const TextureBuffer2D white_texture_;
  const TextureBuffer2D brdf_lut_texture_;

  std::array<int,2> cube_camera_index_;

  struct RenderBuffer {
    explicit RenderBuffer(const int resolution);
    ~RenderBuffer();
    GLuint render_buffer;
    int resolution;
  };

  struct ShadowMapTarget {
    ShadowMapTarget(const RenderBuffer &render_buffer);
    ~ShadowMapTarget();
    GLuint texture;
    GLuint frame_buffer;
  };

  /** Shadow maps. */
  const RenderBuffer shadow_maps_render_buffer_;
  const std::array<ShadowMapTarget, 2> shadow_maps_;

  struct EnvironmentMapTarget {
    EnvironmentMapTarget(const RenderBuffer &render_buffer);
    ~EnvironmentMapTarget();
    GLuint texture;
    GLuint frame_buffer;
  };

  /** Environment map targets. */
  const RenderBuffer environment_render_buffer_;
  const std::array<EnvironmentMapTarget, 2> environment_maps_targets;

  static const std::map<const unsigned int, std::string> shader_types_;

};
}
}<commit_msg>Program inheritance.<commit_after>#pragma once
#include <glad/glad.h>
#include <optional>
#include <initializer_list>
#include <unordered_map>
#include <array>
#include <future>
#include <mos/gfx/scene.hpp>
#include <mos/gfx/texture_2d.hpp>
#include <mos/gfx/model.hpp>
#include <mos/gfx/text.hpp>
#include <mos/gfx/particle_cloud.hpp>
#include <mos/gfx/light.hpp>
#include <mos/gfx/target.hpp>
#include <mos/gfx/camera.hpp>
#include <mos/gfx/environment_light.hpp>
#include <mos/gfx/fog.hpp>
#include <mos/gfx/box.hpp>
#include <mos/gfx/scenes.hpp>
#include <mos/gfx/lights.hpp>

namespace mos {
namespace gfx {

/** Render geometry/models with OpenGL. */
class Renderer final {
public:
  /** Inits the renderer, creates an OpenGL context with GLEW. */
  Renderer(const glm::vec4 &color, const glm::ivec2 &resolution);

  ~Renderer();

  /** Loads a model into renderers own memory. */
  void load(const Model &model);

  void load(const Models & models);

  /** Unloads a model from renderers own memory. */
  void unload(const Model &model);

  /** Load a mesh in to memory. */
  void load(const Mesh &mesh);
  void load(const SharedMesh &mesh);

  /** Unloads a mesh from memory. */
  void unload(const Mesh &mesh);
  void unload(const SharedMesh &mesh);

  /** Loads a shared texture into renderer memory. */
  void load(const SharedTexture2D &texture);

  /** Loads a texture into renderer memory. */
  void load_or_update(const Texture2D &texture);

  /** Unloads a shared texture from renderer memory. */
  void unload(const SharedTexture2D &texture);

  /** Render multiple scenes. */
  void render(const Scenes &scenes,
              const glm::vec4 &color = {.0f, .0f, .0f, 1.0f},
              const glm::ivec2 &resolution = glm::ivec2(128, 128));

  /** Clear all internal buffers/memory. */
  void clear_buffers();

private:
  using TimePoint =  std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds>;

  struct Buffer {
    GLuint id;
    TimePoint modified;
  };

  class TextureBuffer2D {
  public:
    explicit TextureBuffer2D(const Texture2D &texture_2d);
    TextureBuffer2D(const GLuint internal_format,
                    const GLuint external_format,
                    const int width,
                    const int height,
                    const GLuint wrap,
                    const void *data,
                    const bool mipmaps,
                    const TimePoint &modified = std::chrono::system_clock::now());
    ~TextureBuffer2D();
    GLuint texture;
    TimePoint modified;
  };

  class Shader {
  public:
    Shader(const std::string &source, const GLuint type, const std::string& name);
    ~Shader();
    GLuint id;
  };

  struct Program {
    Program();
    ~Program();
    GLuint program;
  };

  /** Uniforms for the particle shader program. */
  struct ParticleProgram : public Program {
    ParticleProgram();
    ~ParticleProgram();
    GLint mvp;
    GLint mv;
    GLint p;
    GLint texture;
    GLint resolution;
  };

  /** Uniforms for the bounding box shader program. */
  struct BoxProgram : public Program {
    BoxProgram();
    ~BoxProgram();
    GLint mvp;
  };

  struct MultisampleProgram : public Program {
    MultisampleProgram();
    ~MultisampleProgram();
    GLint color_texture;
    GLint depth_texture;
  };

  struct BloomProgram : public Program {
    BloomProgram();
    ~BloomProgram();
    GLint color_texture;
    GLint bright_color_texture;
    GLint strength;
  };

  struct BlurProgram : public Program {
    BlurProgram();
    ~BlurProgram();
    GLint color_texture;
    GLint horizontal;
  };

  struct DepthProgram : public Program {
    DepthProgram();
    ~DepthProgram();
    GLint model_view_projection_matrix;
  };

  /** Uniforms for the standard shader. */
  class StandardProgram : public Program {
  public:
    StandardProgram();
    ~StandardProgram();
    GLint model_view_projection_matrix;
    GLint model_matrix;
    GLint normal_matrix;
    std::array<GLint,2> depth_bias_mvps;

    struct EnvironmentUniforms {
      GLint map;
      GLint position;
      GLint extent;
      GLint strength;
    };
    std::array<EnvironmentUniforms, 2> environment_maps;

    GLint material_albedo_map;
    GLint material_emission_map;
    GLint material_normal_map;
    GLint material_metallic_map;
    GLint material_roughness_map;
    GLint material_ambient_occlusion_map;
    GLint material_albedo;
    GLint material_roughness;
    GLint material_metallic;
    GLint material_opacity;
    GLint material_emission;
    GLint material_ambient_occlusion;
    GLint material_emission_strength;
    GLint material_factor;

    GLint camera_resolution;
    GLint camera_position;

    struct LightUniforms {
      GLint position;
      GLint color;
      GLint view;
      GLint projection;
      GLint angle;
      GLint direction;
    };

    std::array<GLuint, 2> shadow_maps;
    std::array<LightUniforms, 2> lights;

    GLint fog_color_near;
    GLint fog_color_far;
    GLint fog_attenuation_factor;

    GLint brdf_lut;
  };

  void render_texture_targets(const Scene &scene);

  void render_scene(const Camera &camera,
                    const Scene &scene,
                    const glm::vec2 &resolution);

  void render_shadow_maps(const Models &models,
                          const Lights &lights);

  void render_environment(const Scene &scene,
                          const glm::vec4 &clear_color);

  void render_boxes(const Boxes & boxes,
                    const mos::gfx::Camera &camera);

  void render_particles(const ParticleClouds &clouds,
                        const mos::gfx::Camera &camera,
                        const glm::vec2 &resolution);

  void render_model(const Model &model,
                    const glm::mat4 &transform,
                    const Camera &camera,
                    const Lights &lights,
                    const EnvironmentLights &environment_lights,
                    const Fog &fog,
                    const glm::vec2 &resolution,
                    const StandardProgram& program);

  void render_model_depth(const Model &model,
                          const glm::mat4 &transform,
                          const Camera &camera,
                          const glm::vec2 &resolution,
                          const DepthProgram& program);

  /** Clear color and depth. */
  void clear(const glm::vec4 &color);
  void clear_depth();
  void clear_color(const glm::vec4 &color);

  static bool check_program(const unsigned int program,
                            const std::string &name);

  static void link_program(const GLuint program,
                    const std::string& name);

  const StandardProgram standard_program_;
  const ParticleProgram particle_program_;
  const BoxProgram box_program_;
  const DepthProgram depth_program_;
  const MultisampleProgram multisample_program_;
  const BloomProgram bloom_program_;
  const BlurProgram blur_program_;

  std::unordered_map<unsigned int, GLuint> frame_buffers_;
  std::unordered_map<unsigned int, GLuint> render_buffers;
  std::unordered_map<unsigned int, GLuint> pixel_buffers_;
  std::unordered_map<unsigned int, std::unique_ptr<TextureBuffer2D>> textures_;
  std::unordered_map<unsigned int, Buffer> array_buffers_;
  std::unordered_map<unsigned int, Buffer> element_array_buffers_;
  std::unordered_map<unsigned int, GLuint> vertex_arrays_;

  struct StandardTarget{
    StandardTarget(const glm::vec2 &resolution);
    ~StandardTarget();
    GLuint frame_buffer;
    GLuint texture;
    GLuint depth_texture;
  };

  const StandardTarget standard_target_;

  struct MultiTarget {
    MultiTarget(const glm::vec2 &resolution);
    ~MultiTarget();
    GLuint frame_buffer;
    GLuint color_texture;
    GLuint bright_texture;
  };

  const MultiTarget multi_target_;

  struct BlurTarget {
    BlurTarget(const glm::vec2 &resolution);
    ~BlurTarget();
    GLuint frame_buffer;
    GLuint texture;
  };

  const BlurTarget blur_target0_;
  const BlurTarget blur_target1_;

  struct Quad {
    Quad();
    ~Quad();
    GLuint vertex_array;
    GLuint buffer;
  };

  const Quad quad_;

  struct Box {
    Box();
    ~Box();
    GLuint buffer;
    GLuint element_buffer;
    GLuint vertex_array;
  };

  const Box box;

  const TextureBuffer2D black_texture_;
  const TextureBuffer2D white_texture_;
  const TextureBuffer2D brdf_lut_texture_;

  std::array<int,2> cube_camera_index_;

  struct RenderBuffer {
    explicit RenderBuffer(const int resolution);
    ~RenderBuffer();
    GLuint render_buffer;
    int resolution;
  };

  struct ShadowMapTarget {
    ShadowMapTarget(const RenderBuffer &render_buffer);
    ~ShadowMapTarget();
    GLuint texture;
    GLuint frame_buffer;
  };

  /** Shadow maps. */
  const RenderBuffer shadow_maps_render_buffer_;
  const std::array<ShadowMapTarget, 2> shadow_maps_;

  struct EnvironmentMapTarget {
    EnvironmentMapTarget(const RenderBuffer &render_buffer);
    ~EnvironmentMapTarget();
    GLuint texture;
    GLuint frame_buffer;
  };

  /** Environment map targets. */
  const RenderBuffer environment_render_buffer_;
  const std::array<EnvironmentMapTarget, 2> environment_maps_targets;

  static const std::map<const unsigned int, std::string> shader_types_;

};
}
}<|endoftext|>


<commit_before> /*
    This file is part of Fast Slater.

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

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

    You should have received a copy of the GNU General Public License
    along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef NUMERICAL_MATRIX_HPP
#define NUMERICAL_MATRIX_HPP

#include <config.h>

namespace numerical {

  template <class T,
            class Allocator = std::allocator<T>,
            class MatrixImpl = impl::SerialMatrixImplementation<T, Allocator> >
  class Matrix {
  public:
    typedef T value_type;
    typedef Allocator allocator_type;
    typedef MatrixImpl matrix_implementation_type;

  public:
    serial Matrix(const size_t n);
    Matrix(const size_t rows, const size_t cols);
    Matrix(const Matrix& other);
    ~Matrix();

#ifdef HAS_MOVE_CONSTRUCTOR
    Matrix(Matrix&& other);
#endif

#ifdef HAS_MOVE_ASSIGNMENT
    Matrix& operator=(Matrix&& other);
#endif

    Matrix& operator=(const Matrix& other);

    T& operator()(const size_t row, const size_t col);
    T& operator()(const size_t row, const size_t col) const;

    Matrix& operator+=(const Matrix& other);
    Matrix& operator-=(const Matrix& other);
    Matrix& operator*=(const Matrix& other);

    Matrix& operator+=(const T& other);
    Matrix& operator-=(const T& other);
    Matrix& operator*=(const T& other);
    Matrix& operator/=(const T& other);

  public:
    T* data() const;
    size_t rows() const;
    size_t cols() const;
    constexpr allocator_type get_allocator() const;

  private:
    static matrix_implementation_type _impl;
  };

  template <class T,
            class _Alloc,
            class _Impl>
  Matrix<T, _Alloc, _Impl>
  operator-(const Matrix<T, _Alloc, _Impl>&);

  template <class T,
            class _Alloc,
            class _Impl>
  Matrix<T, _Alloc, _Impl>
  operator+(const Matrix<T, _Alloc, _Impl>&,
            const Matrix<T, _Alloc, _Impl>&);

  template <class T,
            class _Alloc,
            class _Impl>
  Matrix<T, _Alloc, _Impl>
  operator-(const Matrix<T, _Alloc, _Impl>&,
            const Matrix<T, _Alloc, _Impl>&);

  template <class T,
            class _Alloc,
            class _Impl>
  Matrix<T, _Alloc, _Impl>
  operator*(const Matrix<T, _Alloc, _Impl>&,
            const Matrix<T, _Alloc, _Impl>&);

  template <class T,
            class _Alloc,
            class _Impl>
  Matrix<T, _Alloc, _Impl>
  operator+(const Matrix<T, _Alloc, _Impl>&,
            const T&);

  template <class T,
            class _Alloc,
            class _Impl>
  Matrix<T, _Alloc, _Impl>
  operator-(const Matrix<T, _Alloc, _Impl>&,
            const T&);

  template <class T,
            class _Alloc,
            class _Impl>
  Matrix<T, _Alloc, _Impl>
  operator*(const Matrix<T, _Alloc, _Impl>&,
            const T&);

  template <class T,
            class _Alloc,
            class _Impl>
  Matrix<T, _Alloc, _Impl>
  operator+(const T&,
            const Matrix<T, _Alloc, _Impl>&);

  template <class T,
            class _Alloc,
            class _Impl>
  Matrix<T, _Alloc, _Impl>
  operator-(const T&,
            const Matrix<T, _Alloc, _Impl>&);

  template <class T,
            class _Alloc,
            class _Impl>
  Matrix<T, _Alloc, _Impl>
  operator*(const T&,
            const Matrix<T, _Alloc, _Impl>&);

  template <class T,
            class _Alloc,
            class _Impl>
  bool operator==(const Matrix<T, _Alloc, _Impl>&,
                  const Matrix<T, _Alloc, _Impl>&);

  template <class T,
            class _Alloc,
            class _Impl>
  bool operator!=(const Matrix<T, _Alloc, _Impl>&,
                  const Matrix<T, _Alloc, _Impl>&);
}

#include <implementation/matrix.cpp>

#endif
<commit_msg>Bug fix: compiler error in matrix.hpp.<commit_after> /*
    This file is part of Fast Slater.

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

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

    You should have received a copy of the GNU General Public License
    along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef NUMERICAL_MATRIX_HPP
#define NUMERICAL_MATRIX_HPP

#include <config.h>

namespace numerical {

  template <class T,
            class Allocator = std::allocator<T>,
            class MatrixImpl = impl::SerialMatrixImplementation<T, Allocator> >
  class Matrix {
  public:
    typedef T value_type;
    typedef Allocator allocator_type;
    typedef MatrixImpl matrix_implementation_type;

  public:
    explicit Matrix(const size_t n);
    Matrix(const size_t rows, const size_t cols);
    Matrix(const Matrix& other);
    ~Matrix();

#ifdef HAS_MOVE_CONSTRUCTOR
    Matrix(Matrix&& other);
#endif

#ifdef HAS_MOVE_ASSIGNMENT
    Matrix& operator=(Matrix&& other);
#endif

    Matrix& operator=(const Matrix& other);

    T& operator()(const size_t row, const size_t col);
    T& operator()(const size_t row, const size_t col) const;

    Matrix& operator+=(const Matrix& other);
    Matrix& operator-=(const Matrix& other);
    Matrix& operator*=(const Matrix& other);

    Matrix& operator+=(const T& other);
    Matrix& operator-=(const T& other);
    Matrix& operator*=(const T& other);
    Matrix& operator/=(const T& other);

  public:
    T* data() const;
    size_t rows() const;
    size_t cols() const;
    constexpr allocator_type get_allocator() const;

  private:
    static matrix_implementation_type _impl;
  };

  template <class T,
            class _Alloc,
            class _Impl>
  Matrix<T, _Alloc, _Impl>
  operator-(const Matrix<T, _Alloc, _Impl>&);

  template <class T,
            class _Alloc,
            class _Impl>
  Matrix<T, _Alloc, _Impl>
  operator+(const Matrix<T, _Alloc, _Impl>&,
            const Matrix<T, _Alloc, _Impl>&);

  template <class T,
            class _Alloc,
            class _Impl>
  Matrix<T, _Alloc, _Impl>
  operator-(const Matrix<T, _Alloc, _Impl>&,
            const Matrix<T, _Alloc, _Impl>&);

  template <class T,
            class _Alloc,
            class _Impl>
  Matrix<T, _Alloc, _Impl>
  operator*(const Matrix<T, _Alloc, _Impl>&,
            const Matrix<T, _Alloc, _Impl>&);

  template <class T,
            class _Alloc,
            class _Impl>
  Matrix<T, _Alloc, _Impl>
  operator+(const Matrix<T, _Alloc, _Impl>&,
            const T&);

  template <class T,
            class _Alloc,
            class _Impl>
  Matrix<T, _Alloc, _Impl>
  operator-(const Matrix<T, _Alloc, _Impl>&,
            const T&);

  template <class T,
            class _Alloc,
            class _Impl>
  Matrix<T, _Alloc, _Impl>
  operator*(const Matrix<T, _Alloc, _Impl>&,
            const T&);

  template <class T,
            class _Alloc,
            class _Impl>
  Matrix<T, _Alloc, _Impl>
  operator+(const T&,
            const Matrix<T, _Alloc, _Impl>&);

  template <class T,
            class _Alloc,
            class _Impl>
  Matrix<T, _Alloc, _Impl>
  operator-(const T&,
            const Matrix<T, _Alloc, _Impl>&);

  template <class T,
            class _Alloc,
            class _Impl>
  Matrix<T, _Alloc, _Impl>
  operator*(const T&,
            const Matrix<T, _Alloc, _Impl>&);

  template <class T,
            class _Alloc,
            class _Impl>
  bool operator==(const Matrix<T, _Alloc, _Impl>&,
                  const Matrix<T, _Alloc, _Impl>&);

  template <class T,
            class _Alloc,
            class _Impl>
  bool operator!=(const Matrix<T, _Alloc, _Impl>&,
                  const Matrix<T, _Alloc, _Impl>&);
}

#include <implementation/matrix.cpp>

#endif
<|endoftext|>


<commit_before>/*
 * This file is open source software, licensed to you under the terms
 * of the Apache License, Version 2.0 (the "License").  See the NOTICE file
 * distributed with this work for additional information regarding copyright
 * ownership.  You may not use this file except in compliance with the License.
 *
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
/*
 * Copyright (C) 2015 Cloudius Systems, Ltd.
 */

#pragma once

#include <memory>
#include <seastar/core/scheduling.hh>

namespace seastar {

class task {
    scheduling_group _sg;
protected:
    // Task destruction is performed by run_and_dispose() via a concrete type,
    // so no need for a virtual destructor here. Derived classes that implement
    // run_and_dispose() should be declared final to avoid losing concrete type
    // information via inheritance.
    ~task() = default;
public:
    explicit task(scheduling_group sg = current_scheduling_group()) : _sg(sg) {}
    virtual void run_and_dispose() noexcept = 0;
    scheduling_group group() const { return _sg; }
};

void schedule(task* t) noexcept;
void schedule_urgent(task* t) noexcept;

template <typename Func>
class lambda_task final : public task {
    Func _func;
public:
    lambda_task(scheduling_group sg, const Func& func) : task(sg), _func(func) {}
    lambda_task(scheduling_group sg, Func&& func) : task(sg), _func(std::move(func)) {}
    virtual void run_and_dispose() noexcept override {
        _func();
        delete this;
    }
};

template <typename Func>
inline
task*
make_task(Func&& func) noexcept {
    return new lambda_task<Func>(current_scheduling_group(), std::forward<Func>(func));
}

template <typename Func>
inline
task*
make_task(scheduling_group sg, Func&& func) noexcept {
    return new lambda_task<Func>(sg, std::forward<Func>(func));
}

}
<commit_msg>task: specify the default constructor as noexcept<commit_after>/*
 * This file is open source software, licensed to you under the terms
 * of the Apache License, Version 2.0 (the "License").  See the NOTICE file
 * distributed with this work for additional information regarding copyright
 * ownership.  You may not use this file except in compliance with the License.
 *
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
/*
 * Copyright (C) 2015 Cloudius Systems, Ltd.
 */

#pragma once

#include <memory>
#include <seastar/core/scheduling.hh>

namespace seastar {

class task {
    scheduling_group _sg;
protected:
    // Task destruction is performed by run_and_dispose() via a concrete type,
    // so no need for a virtual destructor here. Derived classes that implement
    // run_and_dispose() should be declared final to avoid losing concrete type
    // information via inheritance.
    ~task() = default;
public:
    explicit task(scheduling_group sg = current_scheduling_group()) noexcept : _sg(sg) {}
    virtual void run_and_dispose() noexcept = 0;
    scheduling_group group() const { return _sg; }
};

void schedule(task* t) noexcept;
void schedule_urgent(task* t) noexcept;

template <typename Func>
class lambda_task final : public task {
    Func _func;
public:
    lambda_task(scheduling_group sg, const Func& func) : task(sg), _func(func) {}
    lambda_task(scheduling_group sg, Func&& func) : task(sg), _func(std::move(func)) {}
    virtual void run_and_dispose() noexcept override {
        _func();
        delete this;
    }
};

template <typename Func>
inline
task*
make_task(Func&& func) noexcept {
    return new lambda_task<Func>(current_scheduling_group(), std::forward<Func>(func));
}

template <typename Func>
inline
task*
make_task(scheduling_group sg, Func&& func) noexcept {
    return new lambda_task<Func>(sg, std::forward<Func>(func));
}

}
<|endoftext|>