mirror of
https://github.com/mawww/kakoune.git
synced 2024-12-27 13:44:32 +03:00
Merge branch 'master' into remove-buffer-change-listener
Conflicts: src/highlighters.cc
This commit is contained in:
commit
211b78f536
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
#include "event_manager.hh"
|
#include "event_manager.hh"
|
||||||
|
|
||||||
|
#include <sys/select.h>
|
||||||
|
|
||||||
namespace Kakoune
|
namespace Kakoune
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -27,30 +29,41 @@ Buffer* create_fifo_buffer(String name, int fd, bool scroll)
|
|||||||
Buffer* buffer = new Buffer(std::move(name), Buffer::Flags::Fifo | Buffer::Flags::NoUndo);
|
Buffer* buffer = new Buffer(std::move(name), Buffer::Flags::Fifo | Buffer::Flags::NoUndo);
|
||||||
|
|
||||||
auto watcher = new FDWatcher(fd, [buffer, scroll](FDWatcher& watcher) {
|
auto watcher = new FDWatcher(fd, [buffer, scroll](FDWatcher& watcher) {
|
||||||
constexpr size_t buffer_size = 1024 * 16;
|
constexpr size_t buffer_size = 2048;
|
||||||
char data[buffer_size];
|
char data[buffer_size];
|
||||||
ssize_t count = read(watcher.fd(), data, buffer_size);
|
const int fifo = watcher.fd();
|
||||||
auto pos = buffer->end()-1;
|
timeval tv{ 0, 0 };
|
||||||
|
fd_set rfds;
|
||||||
bool prevent_scrolling = pos == buffer->begin() and not scroll;
|
ssize_t count = 0;
|
||||||
if (prevent_scrolling)
|
do
|
||||||
++pos;
|
|
||||||
|
|
||||||
buffer->insert(pos, count > 0 ? String(data, data+count)
|
|
||||||
: "*** kak: fifo closed ***\n");
|
|
||||||
|
|
||||||
if (prevent_scrolling)
|
|
||||||
{
|
{
|
||||||
buffer->erase(buffer->begin(), buffer->begin()+1);
|
count = read(fifo, data, buffer_size);
|
||||||
buffer->insert(buffer->end(), "\n");
|
auto pos = buffer->end()-1;
|
||||||
|
|
||||||
|
bool prevent_scrolling = pos == buffer->begin() and not scroll;
|
||||||
|
if (prevent_scrolling)
|
||||||
|
++pos;
|
||||||
|
|
||||||
|
buffer->insert(pos, count > 0 ? String(data, data+count)
|
||||||
|
: "*** kak: fifo closed ***\n");
|
||||||
|
|
||||||
|
if (prevent_scrolling)
|
||||||
|
{
|
||||||
|
buffer->erase(buffer->begin(), buffer->begin()+1);
|
||||||
|
buffer->insert(buffer->end(), "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
FD_ZERO(&rfds);
|
||||||
|
FD_SET(fifo, &rfds);
|
||||||
}
|
}
|
||||||
|
while (count > 0 and select(fifo+1, &rfds, nullptr, nullptr, &tv) == 1);
|
||||||
|
|
||||||
if (count <= 0)
|
if (count <= 0)
|
||||||
{
|
{
|
||||||
kak_assert(buffer->flags() & Buffer::Flags::Fifo);
|
kak_assert(buffer->flags() & Buffer::Flags::Fifo);
|
||||||
buffer->flags() &= ~Buffer::Flags::Fifo;
|
buffer->flags() &= ~Buffer::Flags::Fifo;
|
||||||
buffer->flags() &= ~Buffer::Flags::NoUndo;
|
buffer->flags() &= ~Buffer::Flags::NoUndo;
|
||||||
close(watcher.fd());
|
close(fifo);
|
||||||
delete &watcher;
|
delete &watcher;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -64,6 +64,7 @@ ColorRegistry::ColorRegistry()
|
|||||||
{ "StatusCursor", { Colors::Black, Colors::Cyan } },
|
{ "StatusCursor", { Colors::Black, Colors::Cyan } },
|
||||||
{ "Prompt", { Colors::Yellow, Colors::Default } },
|
{ "Prompt", { Colors::Yellow, Colors::Default } },
|
||||||
{ "MatchingChar", { Colors::Default, Colors::Magenta } },
|
{ "MatchingChar", { Colors::Default, Colors::Magenta } },
|
||||||
|
{ "Search", { Colors::Default, Colors::Magenta } },
|
||||||
}
|
}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@ -333,7 +333,7 @@ const CommandDesc force_delbuf_cmd = {
|
|||||||
single_optional_name_param,
|
single_optional_name_param,
|
||||||
CommandFlags::None,
|
CommandFlags::None,
|
||||||
buffer_completer,
|
buffer_completer,
|
||||||
delete_buffer<false>
|
delete_buffer<true>
|
||||||
};
|
};
|
||||||
|
|
||||||
const CommandDesc namebuf_cmd = {
|
const CommandDesc namebuf_cmd = {
|
||||||
|
13
src/coord.hh
13
src/coord.hh
@ -12,14 +12,17 @@ struct LineAndColumn
|
|||||||
LineType line;
|
LineType line;
|
||||||
ColumnType column;
|
ColumnType column;
|
||||||
|
|
||||||
|
[[gnu::always_inline]]
|
||||||
constexpr LineAndColumn(LineType line = 0, ColumnType column = 0)
|
constexpr LineAndColumn(LineType line = 0, ColumnType column = 0)
|
||||||
: line(line), column(column) {}
|
: line(line), column(column) {}
|
||||||
|
|
||||||
|
[[gnu::always_inline]]
|
||||||
constexpr EffectiveType operator+(EffectiveType other) const
|
constexpr EffectiveType operator+(EffectiveType other) const
|
||||||
{
|
{
|
||||||
return EffectiveType(line + other.line, column + other.column);
|
return EffectiveType(line + other.line, column + other.column);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[gnu::always_inline]]
|
||||||
EffectiveType& operator+=(EffectiveType other)
|
EffectiveType& operator+=(EffectiveType other)
|
||||||
{
|
{
|
||||||
line += other.line;
|
line += other.line;
|
||||||
@ -27,11 +30,13 @@ struct LineAndColumn
|
|||||||
return *static_cast<EffectiveType*>(this);
|
return *static_cast<EffectiveType*>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[gnu::always_inline]]
|
||||||
constexpr EffectiveType operator-(EffectiveType other) const
|
constexpr EffectiveType operator-(EffectiveType other) const
|
||||||
{
|
{
|
||||||
return EffectiveType(line - other.line, column - other.column);
|
return EffectiveType(line - other.line, column - other.column);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[gnu::always_inline]]
|
||||||
EffectiveType& operator-=(EffectiveType other)
|
EffectiveType& operator-=(EffectiveType other)
|
||||||
{
|
{
|
||||||
line -= other.line;
|
line -= other.line;
|
||||||
@ -39,35 +44,41 @@ struct LineAndColumn
|
|||||||
return *static_cast<EffectiveType*>(this);
|
return *static_cast<EffectiveType*>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[gnu::always_inline]]
|
||||||
constexpr bool operator< (EffectiveType other) const
|
constexpr bool operator< (EffectiveType other) const
|
||||||
{
|
{
|
||||||
return (line != other.line) ? line < other.line
|
return (line != other.line) ? line < other.line
|
||||||
: column < other.column;
|
: column < other.column;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[gnu::always_inline]]
|
||||||
constexpr bool operator<= (EffectiveType other) const
|
constexpr bool operator<= (EffectiveType other) const
|
||||||
{
|
{
|
||||||
return (line != other.line) ? line < other.line
|
return (line != other.line) ? line < other.line
|
||||||
: column <= other.column;
|
: column <= other.column;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[gnu::always_inline]]
|
||||||
constexpr bool operator> (EffectiveType other) const
|
constexpr bool operator> (EffectiveType other) const
|
||||||
{
|
{
|
||||||
return (line != other.line) ? line > other.line
|
return (line != other.line) ? line > other.line
|
||||||
: column > other.column;
|
: column > other.column;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[gnu::always_inline]]
|
||||||
constexpr bool operator>= (EffectiveType other) const
|
constexpr bool operator>= (EffectiveType other) const
|
||||||
{
|
{
|
||||||
return (line != other.line) ? line > other.line
|
return (line != other.line) ? line > other.line
|
||||||
: column >= other.column;
|
: column >= other.column;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[gnu::always_inline]]
|
||||||
constexpr bool operator== (EffectiveType other) const
|
constexpr bool operator== (EffectiveType other) const
|
||||||
{
|
{
|
||||||
return line == other.line and column == other.column;
|
return line == other.line and column == other.column;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[gnu::always_inline]]
|
||||||
constexpr bool operator!= (EffectiveType other) const
|
constexpr bool operator!= (EffectiveType other) const
|
||||||
{
|
{
|
||||||
return line != other.line or column != other.column;
|
return line != other.line or column != other.column;
|
||||||
@ -76,12 +87,14 @@ struct LineAndColumn
|
|||||||
|
|
||||||
struct ByteCoord : LineAndColumn<ByteCoord, LineCount, ByteCount>
|
struct ByteCoord : LineAndColumn<ByteCoord, LineCount, ByteCount>
|
||||||
{
|
{
|
||||||
|
[[gnu::always_inline]]
|
||||||
constexpr ByteCoord(LineCount line = 0, ByteCount column = 0)
|
constexpr ByteCoord(LineCount line = 0, ByteCount column = 0)
|
||||||
: LineAndColumn(line, column) {}
|
: LineAndColumn(line, column) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CharCoord : LineAndColumn<CharCoord, LineCount, CharCount>
|
struct CharCoord : LineAndColumn<CharCoord, LineCount, CharCount>
|
||||||
{
|
{
|
||||||
|
[[gnu::always_inline]]
|
||||||
constexpr CharCoord(LineCount line = 0, CharCount column = 0)
|
constexpr CharCoord(LineCount line = 0, CharCount column = 0)
|
||||||
: LineAndColumn(line, column) {}
|
: LineAndColumn(line, column) {}
|
||||||
};
|
};
|
||||||
|
@ -37,18 +37,25 @@ public:
|
|||||||
: m_type(Text), m_text(std::move(str)), colors(colors), attribute(attribute)
|
: m_type(Text), m_text(std::move(str)), colors(colors), attribute(attribute)
|
||||||
{ check_invariant(); }
|
{ check_invariant(); }
|
||||||
|
|
||||||
String content() const
|
StringView content() const
|
||||||
{
|
{
|
||||||
switch (m_type)
|
switch (m_type)
|
||||||
{
|
{
|
||||||
case BufferRange:
|
case BufferRange:
|
||||||
return m_buffer->string(m_begin, m_end);
|
{
|
||||||
|
auto& line = (*m_buffer)[m_begin.line];
|
||||||
|
if (m_begin.line == m_end.line)
|
||||||
|
return line.substr(m_begin.column, m_end.column - m_begin.column);
|
||||||
|
else if (m_begin.line+1 == m_end.line and m_end.column == 0)
|
||||||
|
return line.substr(m_begin.column);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case Text:
|
case Text:
|
||||||
case ReplacedBufferRange:
|
case ReplacedBufferRange:
|
||||||
return m_text;
|
return m_text;
|
||||||
}
|
}
|
||||||
kak_assert(false);
|
kak_assert(false);
|
||||||
return 0;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
CharCount length() const
|
CharCount length() const
|
||||||
|
@ -195,8 +195,8 @@ public:
|
|||||||
private:
|
private:
|
||||||
struct Cache
|
struct Cache
|
||||||
{
|
{
|
||||||
BufferRange m_range;
|
std::pair<LineCount, LineCount> m_range;
|
||||||
size_t m_timestamp = 0;
|
size_t m_timestamp = 0;
|
||||||
std::vector<std::vector<std::pair<ByteCoord, ByteCoord>>> m_matches;
|
std::vector<std::vector<std::pair<ByteCoord, ByteCoord>>> m_matches;
|
||||||
};
|
};
|
||||||
BufferSideCache<Cache> m_cache;
|
BufferSideCache<Cache> m_cache;
|
||||||
@ -208,18 +208,21 @@ private:
|
|||||||
{
|
{
|
||||||
Cache& cache = m_cache.get(buffer);
|
Cache& cache = m_cache.get(buffer);
|
||||||
|
|
||||||
|
LineCount first_line = range.first.line;
|
||||||
|
LineCount last_line = std::min(buffer.line_count()-1, range.second.line);
|
||||||
|
|
||||||
if (buffer.timestamp() == cache.m_timestamp and
|
if (buffer.timestamp() == cache.m_timestamp and
|
||||||
range.first >= cache.m_range.first and
|
first_line >= cache.m_range.first and
|
||||||
range.second <= cache.m_range.second)
|
last_line <= cache.m_range.second)
|
||||||
return cache;
|
return cache;
|
||||||
|
|
||||||
cache.m_range.first = buffer.clamp({range.first.line - 10, 0});
|
cache.m_range.first = std::max(0_line, first_line - 10);
|
||||||
cache.m_range.second = buffer.next(buffer.clamp({range.second.line + 10, INT_MAX}));
|
cache.m_range.second = std::min(buffer.line_count()-1, last_line+10);
|
||||||
cache.m_timestamp = buffer.timestamp();
|
cache.m_timestamp = buffer.timestamp();
|
||||||
|
|
||||||
cache.m_matches.clear();
|
cache.m_matches.clear();
|
||||||
RegexIterator re_it{buffer.iterator_at(cache.m_range.first),
|
RegexIterator re_it{buffer.iterator_at(cache.m_range.first),
|
||||||
buffer.iterator_at(cache.m_range.second), m_regex};
|
buffer.iterator_at(cache.m_range.second+1), m_regex};
|
||||||
RegexIterator re_end;
|
RegexIterator re_end;
|
||||||
for (; re_it != re_end; ++re_it)
|
for (; re_it != re_end; ++re_it)
|
||||||
{
|
{
|
||||||
@ -266,12 +269,14 @@ HighlighterAndId colorize_regex_factory(HighlighterParameters params)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename RegexGetter>
|
template<typename RegexGetter, typename ColorGetter>
|
||||||
class DynamicRegexHighlighter
|
class DynamicRegexHighlighter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DynamicRegexHighlighter(const ColorSpec& colors, RegexGetter getter)
|
DynamicRegexHighlighter(RegexGetter regex_getter, ColorGetter color_getter)
|
||||||
: m_regex_getter(getter), m_colors(colors), m_colorizer(Regex(), m_colors) {}
|
: m_regex_getter(std::move(regex_getter)),
|
||||||
|
m_color_getter(std::move(color_getter)),
|
||||||
|
m_colorizer(Regex(), ColorSpec{}) {}
|
||||||
|
|
||||||
void operator()(const Context& context, HighlightFlags flags, DisplayBuffer& display_buffer)
|
void operator()(const Context& context, HighlightFlags flags, DisplayBuffer& display_buffer)
|
||||||
{
|
{
|
||||||
@ -279,40 +284,56 @@ public:
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
Regex regex = m_regex_getter(context);
|
Regex regex = m_regex_getter(context);
|
||||||
if (regex != m_last_regex)
|
ColorSpec color = m_color_getter(context);
|
||||||
|
if (regex != m_last_regex or color != m_last_color)
|
||||||
{
|
{
|
||||||
m_last_regex = regex;
|
m_last_regex = regex;
|
||||||
|
m_last_color = color;
|
||||||
if (not m_last_regex.empty())
|
if (not m_last_regex.empty())
|
||||||
m_colorizer = RegexColorizer{m_last_regex, m_colors};
|
m_colorizer = RegexColorizer{m_last_regex, color};
|
||||||
}
|
}
|
||||||
if (not m_last_regex.empty())
|
if (not m_last_regex.empty() and not m_last_color.empty())
|
||||||
m_colorizer(context, flags, display_buffer);
|
m_colorizer(context, flags, display_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Regex m_last_regex;
|
Regex m_last_regex;
|
||||||
ColorSpec m_colors;
|
|
||||||
RegexColorizer m_colorizer;
|
|
||||||
RegexGetter m_regex_getter;
|
RegexGetter m_regex_getter;
|
||||||
|
|
||||||
|
ColorSpec m_last_color;
|
||||||
|
ColorGetter m_color_getter;
|
||||||
|
|
||||||
|
RegexColorizer m_colorizer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename RegexGetter, typename ColorGetter>
|
||||||
|
DynamicRegexHighlighter<RegexGetter, ColorGetter>
|
||||||
|
make_dynamic_regex_highlighter(RegexGetter regex_getter, ColorGetter color_getter)
|
||||||
|
{
|
||||||
|
return DynamicRegexHighlighter<RegexGetter, ColorGetter>(
|
||||||
|
std::move(regex_getter), std::move(color_getter));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
HighlighterAndId highlight_search_factory(HighlighterParameters params)
|
HighlighterAndId highlight_search_factory(HighlighterParameters params)
|
||||||
{
|
{
|
||||||
if (params.size() != 1)
|
if (params.size() != 0)
|
||||||
throw runtime_error("wrong parameter count");
|
throw runtime_error("wrong parameter count");
|
||||||
try
|
auto get_color = [](const Context& context){
|
||||||
{
|
return ColorSpec{ { 0, &Kakoune::get_color("Search") } };
|
||||||
ColorSpec colors { { 0, &get_color(params[0]) } };
|
};
|
||||||
auto get_regex = [](const Context&){
|
auto get_regex = [](const Context&){
|
||||||
auto s = RegisterManager::instance()['/'].values(Context{});
|
auto s = RegisterManager::instance()['/'].values(Context{});
|
||||||
return s.empty() ? Regex{} : Regex{s[0].begin(), s[0].end()};
|
try
|
||||||
|
{
|
||||||
|
return s.empty() ? Regex{} : Regex{s[0].begin(), s[0].end()};
|
||||||
|
}
|
||||||
|
catch (boost::regex_error& err)
|
||||||
|
{
|
||||||
|
return Regex{};
|
||||||
|
}
|
||||||
};
|
};
|
||||||
return {"hlsearch", DynamicRegexHighlighter<decltype(get_regex)>{colors, get_regex}};
|
return {"hlsearch", make_dynamic_regex_highlighter(get_regex, get_color)};
|
||||||
}
|
|
||||||
catch (boost::regex_error& err)
|
|
||||||
{
|
|
||||||
throw runtime_error(String("regex error: ") + err.what());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HighlighterAndId highlight_regex_option_factory(HighlighterParameters params)
|
HighlighterAndId highlight_regex_option_factory(HighlighterParameters params)
|
||||||
@ -320,13 +341,19 @@ HighlighterAndId highlight_regex_option_factory(HighlighterParameters params)
|
|||||||
if (params.size() != 2)
|
if (params.size() != 2)
|
||||||
throw runtime_error("wrong parameter count");
|
throw runtime_error("wrong parameter count");
|
||||||
|
|
||||||
ColorSpec colors { { 0, &get_color(params[1]) } };
|
const ColorPair& color = get_color(params[1]);
|
||||||
|
auto get_color = [&](const Context&){
|
||||||
|
return ColorSpec{ { 0, &color } };
|
||||||
|
};
|
||||||
|
|
||||||
String option_name = params[0];
|
String option_name = params[0];
|
||||||
// verify option type now
|
// verify option type now
|
||||||
GlobalOptions::instance()[option_name].get<Regex>();
|
GlobalOptions::instance()[option_name].get<Regex>();
|
||||||
|
|
||||||
auto get_regex = [option_name](const Context& context){ return context.options()[option_name].get<Regex>(); };
|
auto get_regex = [option_name](const Context& context){
|
||||||
return {"hloption_" + option_name, DynamicRegexHighlighter<decltype(get_regex)>{colors, get_regex}};
|
return context.options()[option_name].get<Regex>();
|
||||||
|
};
|
||||||
|
return {"hloption_" + option_name, make_dynamic_regex_highlighter(get_regex, get_color)};
|
||||||
}
|
}
|
||||||
|
|
||||||
void expand_tabulations(const Context& context, HighlightFlags flags, DisplayBuffer& display_buffer)
|
void expand_tabulations(const Context& context, HighlightFlags flags, DisplayBuffer& display_buffer)
|
||||||
@ -470,7 +497,7 @@ void show_matching_char(const Context& context, HighlightFlags flags, DisplayBuf
|
|||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
if (it != end)
|
if (it != end or (*end == pair.first and level == 1))
|
||||||
highlight_range(display_buffer, it.coord(), (it+1).coord(), false,
|
highlight_range(display_buffer, it.coord(), (it+1).coord(), false,
|
||||||
[&](DisplayAtom& atom) { atom.colors = colors; });
|
[&](DisplayAtom& atom) { atom.colors = colors; });
|
||||||
break;
|
break;
|
||||||
|
@ -241,8 +241,10 @@ void NCursesUI::draw_line(const DisplayLine& line, CharCount col_index) const
|
|||||||
|
|
||||||
set_color(stdscr, atom.colors);
|
set_color(stdscr, atom.colors);
|
||||||
|
|
||||||
String atom_content = atom.content();
|
StringView content = atom.content();
|
||||||
StringView content = atom_content;
|
if (content.empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
if (content[content.length()-1] == '\n' and
|
if (content[content.length()-1] == '\n' and
|
||||||
content.char_length() - 1 < m_dimensions.column - col_index)
|
content.char_length() - 1 < m_dimensions.column - col_index)
|
||||||
{
|
{
|
||||||
|
31
src/units.hh
31
src/units.hh
@ -10,6 +10,7 @@ template<typename RealType, typename ValueType = int>
|
|||||||
class StronglyTypedNumber
|
class StronglyTypedNumber
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
[[gnu::always_inline]]
|
||||||
explicit constexpr StronglyTypedNumber(ValueType value)
|
explicit constexpr StronglyTypedNumber(ValueType value)
|
||||||
: m_value(value)
|
: m_value(value)
|
||||||
{
|
{
|
||||||
@ -17,72 +18,96 @@ public:
|
|||||||
"RealType is not derived from StronglyTypedNumber");
|
"RealType is not derived from StronglyTypedNumber");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[gnu::always_inline]]
|
||||||
constexpr RealType operator+(RealType other) const
|
constexpr RealType operator+(RealType other) const
|
||||||
{ return RealType(m_value + other.m_value); }
|
{ return RealType(m_value + other.m_value); }
|
||||||
|
|
||||||
|
[[gnu::always_inline]]
|
||||||
constexpr RealType operator-(RealType other) const
|
constexpr RealType operator-(RealType other) const
|
||||||
{ return RealType(m_value - other.m_value); }
|
{ return RealType(m_value - other.m_value); }
|
||||||
|
|
||||||
|
[[gnu::always_inline]]
|
||||||
constexpr RealType operator*(RealType other) const
|
constexpr RealType operator*(RealType other) const
|
||||||
{ return RealType(m_value * other.m_value); }
|
{ return RealType(m_value * other.m_value); }
|
||||||
|
|
||||||
|
[[gnu::always_inline]]
|
||||||
constexpr RealType operator/(RealType other) const
|
constexpr RealType operator/(RealType other) const
|
||||||
{ return RealType(m_value / other.m_value); }
|
{ return RealType(m_value / other.m_value); }
|
||||||
|
|
||||||
|
[[gnu::always_inline]]
|
||||||
RealType& operator+=(RealType other)
|
RealType& operator+=(RealType other)
|
||||||
{ m_value += other.m_value; return static_cast<RealType&>(*this); }
|
{ m_value += other.m_value; return static_cast<RealType&>(*this); }
|
||||||
|
|
||||||
|
[[gnu::always_inline]]
|
||||||
RealType& operator-=(RealType other)
|
RealType& operator-=(RealType other)
|
||||||
{ m_value -= other.m_value; return static_cast<RealType&>(*this); }
|
{ m_value -= other.m_value; return static_cast<RealType&>(*this); }
|
||||||
|
|
||||||
|
[[gnu::always_inline]]
|
||||||
RealType& operator*=(RealType other)
|
RealType& operator*=(RealType other)
|
||||||
{ m_value *= other.m_value; return static_cast<RealType&>(*this); }
|
{ m_value *= other.m_value; return static_cast<RealType&>(*this); }
|
||||||
|
|
||||||
|
[[gnu::always_inline]]
|
||||||
RealType& operator/=(RealType other)
|
RealType& operator/=(RealType other)
|
||||||
{ m_value /= other.m_value; return static_cast<RealType&>(*this); }
|
{ m_value /= other.m_value; return static_cast<RealType&>(*this); }
|
||||||
|
|
||||||
|
[[gnu::always_inline]]
|
||||||
RealType& operator++()
|
RealType& operator++()
|
||||||
{ ++m_value; return static_cast<RealType&>(*this); }
|
{ ++m_value; return static_cast<RealType&>(*this); }
|
||||||
|
|
||||||
|
[[gnu::always_inline]]
|
||||||
RealType& operator--()
|
RealType& operator--()
|
||||||
{ --m_value; return static_cast<RealType&>(*this); }
|
{ --m_value; return static_cast<RealType&>(*this); }
|
||||||
|
|
||||||
|
[[gnu::always_inline]]
|
||||||
RealType operator++(int)
|
RealType operator++(int)
|
||||||
{ RealType backup(static_cast<RealType&>(*this)); ++m_value; return backup; }
|
{ RealType backup(static_cast<RealType&>(*this)); ++m_value; return backup; }
|
||||||
|
|
||||||
|
[[gnu::always_inline]]
|
||||||
RealType operator--(int)
|
RealType operator--(int)
|
||||||
{ RealType backup(static_cast<RealType&>(*this)); --m_value; return backup; }
|
{ RealType backup(static_cast<RealType&>(*this)); --m_value; return backup; }
|
||||||
|
|
||||||
|
[[gnu::always_inline]]
|
||||||
constexpr RealType operator-() const { return RealType(-m_value); }
|
constexpr RealType operator-() const { return RealType(-m_value); }
|
||||||
|
|
||||||
|
[[gnu::always_inline]]
|
||||||
constexpr RealType operator%(RealType other) const
|
constexpr RealType operator%(RealType other) const
|
||||||
{ return RealType(m_value % other.m_value); }
|
{ return RealType(m_value % other.m_value); }
|
||||||
|
|
||||||
|
[[gnu::always_inline]]
|
||||||
RealType& operator%=(RealType other)
|
RealType& operator%=(RealType other)
|
||||||
{ m_value %= other.m_value; return static_cast<RealType&>(*this); }
|
{ m_value %= other.m_value; return static_cast<RealType&>(*this); }
|
||||||
|
|
||||||
|
[[gnu::always_inline]]
|
||||||
constexpr bool operator==(RealType other) const
|
constexpr bool operator==(RealType other) const
|
||||||
{ return m_value == other.m_value; }
|
{ return m_value == other.m_value; }
|
||||||
|
|
||||||
|
[[gnu::always_inline]]
|
||||||
constexpr bool operator!=(RealType other) const
|
constexpr bool operator!=(RealType other) const
|
||||||
{ return m_value != other.m_value; }
|
{ return m_value != other.m_value; }
|
||||||
|
|
||||||
|
[[gnu::always_inline]]
|
||||||
constexpr bool operator<(RealType other) const
|
constexpr bool operator<(RealType other) const
|
||||||
{ return m_value < other.m_value; }
|
{ return m_value < other.m_value; }
|
||||||
|
|
||||||
|
[[gnu::always_inline]]
|
||||||
constexpr bool operator<=(RealType other) const
|
constexpr bool operator<=(RealType other) const
|
||||||
{ return m_value <= other.m_value; }
|
{ return m_value <= other.m_value; }
|
||||||
|
|
||||||
|
[[gnu::always_inline]]
|
||||||
constexpr bool operator>(RealType other) const
|
constexpr bool operator>(RealType other) const
|
||||||
{ return m_value > other.m_value; }
|
{ return m_value > other.m_value; }
|
||||||
|
|
||||||
|
[[gnu::always_inline]]
|
||||||
constexpr bool operator>=(RealType other) const
|
constexpr bool operator>=(RealType other) const
|
||||||
{ return m_value >= other.m_value; }
|
{ return m_value >= other.m_value; }
|
||||||
|
|
||||||
|
[[gnu::always_inline]]
|
||||||
constexpr bool operator!() const
|
constexpr bool operator!() const
|
||||||
{ return !m_value; }
|
{ return !m_value; }
|
||||||
|
|
||||||
|
[[gnu::always_inline]]
|
||||||
explicit constexpr operator ValueType() const { return m_value; }
|
explicit constexpr operator ValueType() const { return m_value; }
|
||||||
|
[[gnu::always_inline]]
|
||||||
explicit constexpr operator bool() const { return m_value; }
|
explicit constexpr operator bool() const { return m_value; }
|
||||||
private:
|
private:
|
||||||
ValueType m_value;
|
ValueType m_value;
|
||||||
@ -90,9 +115,11 @@ private:
|
|||||||
|
|
||||||
struct LineCount : public StronglyTypedNumber<LineCount, int>
|
struct LineCount : public StronglyTypedNumber<LineCount, int>
|
||||||
{
|
{
|
||||||
|
[[gnu::always_inline]]
|
||||||
constexpr LineCount(int value = 0) : StronglyTypedNumber<LineCount>(value) {}
|
constexpr LineCount(int value = 0) : StronglyTypedNumber<LineCount>(value) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
[[gnu::always_inline]]
|
||||||
inline constexpr LineCount operator"" _line(unsigned long long int value)
|
inline constexpr LineCount operator"" _line(unsigned long long int value)
|
||||||
{
|
{
|
||||||
return LineCount(value);
|
return LineCount(value);
|
||||||
@ -100,9 +127,11 @@ inline constexpr LineCount operator"" _line(unsigned long long int value)
|
|||||||
|
|
||||||
struct ByteCount : public StronglyTypedNumber<ByteCount, int>
|
struct ByteCount : public StronglyTypedNumber<ByteCount, int>
|
||||||
{
|
{
|
||||||
|
[[gnu::always_inline]]
|
||||||
constexpr ByteCount(int value = 0) : StronglyTypedNumber<ByteCount>(value) {}
|
constexpr ByteCount(int value = 0) : StronglyTypedNumber<ByteCount>(value) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
[[gnu::always_inline]]
|
||||||
inline constexpr ByteCount operator"" _byte(unsigned long long int value)
|
inline constexpr ByteCount operator"" _byte(unsigned long long int value)
|
||||||
{
|
{
|
||||||
return ByteCount(value);
|
return ByteCount(value);
|
||||||
@ -110,9 +139,11 @@ inline constexpr ByteCount operator"" _byte(unsigned long long int value)
|
|||||||
|
|
||||||
struct CharCount : public StronglyTypedNumber<CharCount, int>
|
struct CharCount : public StronglyTypedNumber<CharCount, int>
|
||||||
{
|
{
|
||||||
|
[[gnu::always_inline]]
|
||||||
constexpr CharCount(int value = 0) : StronglyTypedNumber<CharCount>(value) {}
|
constexpr CharCount(int value = 0) : StronglyTypedNumber<CharCount>(value) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
[[gnu::always_inline]]
|
||||||
inline constexpr CharCount operator"" _char(unsigned long long int value)
|
inline constexpr CharCount operator"" _char(unsigned long long int value)
|
||||||
{
|
{
|
||||||
return CharCount(value);
|
return CharCount(value);
|
||||||
|
Loading…
Reference in New Issue
Block a user