Browse Source

Introduce aids

rexim 5 years ago
parent
commit
e811ffbadd
9 changed files with 467 additions and 357 deletions
  1. 419 0
      src/aids.hpp
  2. 0 6
      src/core.cpp
  3. 0 11
      src/core_defer.cpp
  4. 0 60
      src/core_print.cpp
  5. 0 259
      src/core_string.cpp
  6. 2 7
      src/emote_downloader.cpp
  7. 3 1
      src/vodus.cpp
  8. 31 5
      src/vodus_emotes.cpp
  9. 12 8
      src/vodus_main.cpp

+ 419 - 0
src/aids.hpp

@@ -0,0 +1,419 @@
+// Copyright 2020 Alexey Kutepov <[email protected]>
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// ============================================================
+//
+// aids — 0.2.0 — std replacement for C++. Designed to aid developers
+// to a better programming experience.
+//
+// https://github.com/rexim/aids
+//
+// ============================================================
+//
+// ChangeLog (https://semver.org/ is implied)
+//
+//   0.2.0  unwrap_into
+//          print1 for long int
+//   0.1.0  print1 for long unsigned int
+//          print1 for int
+//          Pad
+//   0.0.3  bugfix for print1 of Maybe<T>
+//   0.0.2  fix sign-unsigned integer comparison in aids::read_file_as_string_view
+//   0.0.1  min, max, clamp,
+//          defer,
+//          Maybe<T>,
+//          String_View,
+//          print, println
+
+#ifndef AIDS_HPP_
+#define AIDS_HPP_
+
+#include <cassert>
+#include <cctype>
+#include <cerrno>
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+
+namespace aids
+{
+    ////////////////////////////////////////////////////////////
+    // ALGORITHM
+    ////////////////////////////////////////////////////////////
+
+    template <typename T>
+    T min(T a, T b)
+    {
+        return a < b ? a : b;
+    }
+
+    template <typename T>
+    T max(T a, T b)
+    {
+        return a > b ? a : b;
+    }
+
+    template <typename T>
+    T clamp(T x, T low, T high)
+    {
+        return min(max(low, x), high);
+    }
+
+    ////////////////////////////////////////////////////////////
+    // DEFER
+    ////////////////////////////////////////////////////////////
+
+    // https://www.reddit.com/r/ProgrammerTIL/comments/58c6dx/til_how_to_defer_in_c/
+    template <typename F>
+    struct saucy_defer {
+        F f;
+        saucy_defer(F f) : f(f) {}
+        ~saucy_defer() { f(); }
+    };
+
+    template <typename F>
+    saucy_defer<F> defer_func(F f)
+    {
+        return saucy_defer<F>(f);
+    }
+
+#define DEFER_1(x, y) x##y
+#define DEFER_2(x, y) DEFER_1(x, y)
+#define DEFER_3(x)    DEFER_2(x, __COUNTER__)
+#define defer(code)   auto DEFER_3(_defer_) = ::aids::defer_func([&](){code;})
+
+    ////////////////////////////////////////////////////////////
+    // MAYBE
+    ////////////////////////////////////////////////////////////
+
+    template <typename T>
+    struct Maybe
+    {
+        bool has_value;
+        T unwrap;
+    };
+
+#define unwrap_into(lvalue, maybe)              \
+    do {                                        \
+        auto maybe_var = (maybe);               \
+        if (!maybe_var.has_value) return {};    \
+        (lvalue) = maybe_var.unwrap;            \
+    } while (0)
+
+    ////////////////////////////////////////////////////////////
+    // STRING_VIEW
+    ////////////////////////////////////////////////////////////
+
+    struct String_View
+    {
+        size_t count;
+        const char *data;
+
+        [[nodiscard]]
+        String_View trim_begin(void) const
+        {
+            String_View view = *this;
+
+            while (view.count != 0 && isspace(*view.data)) {
+                view.data  += 1;
+                view.count -= 1;
+            }
+            return view;
+        }
+
+        [[nodiscard]]
+        String_View trim_end(void) const
+        {
+            String_View view = *this;
+
+            while (view.count != 0 && isspace(*(view.data + view.count - 1))) {
+                view.count -= 1;
+            }
+            return view;
+        }
+
+        [[nodiscard]]
+        String_View trim(void) const
+        {
+            return trim_begin().trim_end();
+        }
+
+        void chop_back(size_t n)
+        {
+            count -= n < count ? n : count;
+        }
+
+        void chop(size_t n)
+        {
+            if (n > count) {
+                data += count;
+                count = 0;
+            } else {
+                data  += n;
+                count -= n;
+            }
+        }
+
+        void grow(size_t n)
+        {
+            count += n;
+        }
+
+        String_View chop_by_delim(char delim)
+        {
+            assert(data);
+
+            size_t i = 0;
+            while (i < count && data[i] != delim) i++;
+            String_View result = {i, data};
+            chop(i + 1);
+
+            return result;
+        }
+
+        String_View chop_word(void)
+        {
+            *this = trim_begin();
+
+            size_t i = 0;
+            while (i < count && !isspace(data[i])) i++;
+
+            String_View result = { i, data };
+
+            count -= i;
+            data  += i;
+
+            return result;
+        }
+
+        template <typename Integer>
+        Maybe<Integer> from_hex() const
+        {
+            Integer result = {};
+
+            for (size_t i = 0; i < count; ++i) {
+                Integer x = data[i];
+                if ('0' <= x && x <= '9') {
+                    x = (Integer) (x - '0');
+                } else if ('a' <= x && x <= 'f') {
+                    x = (Integer) (x - 'a' + 10);
+                } else if ('A' <= x && x <= 'F') {
+                    x = (Integer) (x - 'A' + 10);
+                } else {
+                    return {};
+                }
+                result = result * (Integer) 0x10 + x;
+            }
+
+            return {true, result};
+        }
+
+        template <typename Integer>
+        Maybe<Integer> as_integer() const
+        {
+            Integer sign = 1;
+            Integer number = {};
+            String_View view = *this;
+
+            if (view.count == 0) {
+                return {};
+            }
+
+            if (*view.data == '-') {
+                sign = -1;
+                view.chop(1);
+            }
+
+            while (view.count) {
+                if (!isdigit(*view.data)) {
+                    return {};
+                }
+                number = number * 10 + (*view.data - '0');
+                view.chop(1);
+            }
+
+            return { true, number * sign };
+        }
+
+        Maybe<float> as_float() const
+        {
+            char buffer[300] = {};
+            memcpy(buffer, data, min(sizeof(buffer) - 1, count));
+            char *endptr = NULL;
+            float result = strtof(buffer, &endptr);
+
+            if (buffer > endptr || (size_t) (endptr - buffer) != count) {
+                return {};
+            }
+
+            return {true, result};
+        }
+
+
+        String_View subview(size_t start, size_t count) const
+        {
+            if (start + count <= this->count) {
+                return {count, data + start};
+            }
+
+            return {};
+        }
+
+        bool operator==(String_View view) const
+        {
+            if (this->count != view.count) return false;
+            return memcmp(this->data, view.data, this->count) == 0;
+        }
+
+        bool operator!=(String_View view) const
+        {
+            return !(*this == view);
+        }
+
+        bool has_prefix(String_View prefix) const
+        {
+            return prefix.count <= this->count
+                && this->subview(0, prefix.count) == prefix;
+        }
+    };
+
+    String_View operator ""_sv(const char *data, size_t count)
+    {
+        return {count, data};
+    }
+
+    String_View cstr_as_string_view(const char *cstr)
+    {
+        return {strlen(cstr), cstr};
+    }
+
+    void print1(FILE *stream, String_View view)
+    {
+        fwrite(view.data, 1, view.count, stream);
+    }
+
+    Maybe<String_View> read_file_as_string_view(const char *filename)
+    {
+        FILE *f = fopen(filename, "rb");
+        if (!f) return {};
+        defer(fclose(f));
+
+        int err = fseek(f, 0, SEEK_END);
+        if (err < 0) return {};
+
+        long size = ftell(f);
+        if (size < 0) return {};
+
+        err = fseek(f, 0, SEEK_SET);
+        if (err < 0) return {};
+
+        auto data = malloc(size);
+        if (!data) return {};
+
+        size_t read_size = fread(data, 1, size, f);
+        if (read_size != (size_t) size && ferror(f)) return {};
+
+        return {true, {static_cast<size_t>(size), static_cast<const char*>(data)}};
+    }
+
+    ////////////////////////////////////////////////////////////
+    // PRINT
+    ////////////////////////////////////////////////////////////
+
+    void print1(FILE *stream, const char *s)
+    {
+        fwrite(s, 1, strlen(s), stream);
+    }
+
+    void print1(FILE *stream, char *s)
+    {
+        fwrite(s, 1, strlen(s), stream);
+    }
+
+    void print1(FILE *stream, char c)
+    {
+        fputc(c, stream);
+    }
+
+    void print1(FILE *stream, float f)
+    {
+        fprintf(stream, "%f", f);
+    }
+
+    void print1(FILE *stream, unsigned long long x)
+    {
+        fprintf(stream, "%lld", x);
+    }
+
+    void print1(FILE *stream, long unsigned int x)
+    {
+        fprintf(stream, "%lu", x);
+    }
+
+    void print1(FILE *stream, int x)
+    {
+        fprintf(stream, "%d", x);
+    }
+
+    void print1(FILE *stream, long int x)
+    {
+        fprintf(stream, "%ld", x);
+    }
+
+    template <typename ... Types>
+    void print(FILE *stream, Types... args)
+    {
+        (print1(stream, args), ...);
+    }
+
+    template <typename T>
+    void print1(FILE *stream, Maybe<T> maybe)
+    {
+        if (!maybe.has_value) {
+            print(stream, "None");
+        } else {
+            print(stream, "Some(", maybe.unwrap, ")");
+        }
+    }
+
+    template <typename ... Types>
+    void println(FILE *stream, Types... args)
+    {
+        (print1(stream, args), ...);
+        print1(stream, '\n');
+    }
+
+    struct Pad
+    {
+        size_t n;
+        char c;
+    };
+
+    void print1(FILE *stream, Pad pad)
+    {
+        for (size_t i = 0; i < pad.n; ++i) {
+            fputc(pad.c, stream);
+        }
+    }
+}
+
+#endif  // AIDS_HPP_

+ 0 - 6
src/core.cpp

@@ -1,6 +0,0 @@
-#include <errno.h>
-#include <string.h>
-
-#include "./core_defer.cpp"
-#include "./core_print.cpp"
-#include "./core_string.cpp"

+ 0 - 11
src/core_defer.cpp

@@ -1,11 +0,0 @@
-template <typename F>
-struct Defer
-{
-    Defer(F f): f(f) {}
-    ~Defer() { f(); }
-    F f;
-};
-
-#define CONCAT0(a, b) a##b
-#define CONCAT(a, b) CONCAT0(a, b)
-#define defer(body) Defer CONCAT(defer, __LINE__)([&]() { body; })

+ 0 - 60
src/core_print.cpp

@@ -1,60 +0,0 @@
-void print1(FILE *stream, float f)
-{
-    fprintf(stream, "%f", f);
-}
-
-void print1(FILE *stream, char c)
-{
-    fputc(c, stream);
-}
-
-void print1(FILE *stream, int x)
-{
-    fprintf(stream, "%d", x);
-}
-
-void print1(FILE *stream, long int x)
-{
-    fprintf(stream, "%ld", x);
-}
-
-void print1(FILE *stream, long unsigned int x)
-{
-    fprintf(stream, "%lu", x);
-}
-
-void print1(FILE *stream, uint32_t x)
-{
-    fprintf(stream, "%u", x);
-}
-
-void print1(FILE *stream, const char *cstr)
-{
-    fputs(cstr, stream);
-}
-
-struct Pad
-{
-    size_t n;
-    char c;
-};
-
-void print1(FILE *stream, Pad pad)
-{
-    for (size_t i = 0; i < pad.n; ++i) {
-        fputc(pad.c, stream);
-    }
-}
-
-template <typename... T>
-void print([[maybe_unused]] FILE *stream, T... args)
-{
-    (print1(stream, args), ...);
-}
-
-template <typename... T>
-void println(FILE *stream, T... args)
-{
-    print(stream, args...);
-    fputc('\n', stream);
-}

+ 0 - 259
src/core_string.cpp

@@ -1,259 +0,0 @@
-#include <cctype>
-
-template <typename T>
-struct Maybe
-{
-    bool has_value;
-    T unwrap;
-};
-
-#define ASSIGN_UNWRAP(place, maybe)               \
-    do {                                          \
-        auto __x = (maybe);                       \
-        if (!__x.has_value) return {};            \
-        (place) = __x.unwrap;                     \
-    } while (0)
-
-// TODO(#20): String_View does not support unicode
-struct String_View
-{
-    size_t count;
-    const char *data;
-
-    [[nodiscard]]
-    String_View trim_begin(void) const
-    {
-        String_View view = *this;
-
-        while (view.count != 0 && isspace(*view.data)) {
-            view.data  += 1;
-            view.count -= 1;
-        }
-        return view;
-    }
-
-    [[nodiscard]]
-    String_View trim_end(void) const
-    {
-        String_View view = *this;
-
-        while (view.count != 0 && isspace(*(view.data + view.count - 1))) {
-            view.count -= 1;
-        }
-        return view;
-    }
-
-    [[nodiscard]]
-    String_View trim(void) const
-    {
-        return trim_begin().trim_end();
-    }
-
-    void chop_back(size_t n)
-    {
-        count -= n < count ? n : count;
-    }
-
-    void chop(size_t n)
-    {
-        if (n > count) {
-            data += count;
-            count = 0;
-        } else {
-            data  += n;
-            count -= n;
-        }
-    }
-
-    String_View chop_by_delim(char delim)
-    {
-        assert(data);
-
-        size_t i = 0;
-        while (i < count && data[i] != delim) i++;
-        String_View result = {i, data};
-        chop(i + 1);
-
-        return result;
-    }
-
-    String_View chop_word(void)
-    {
-        *this = trim_begin();
-
-        size_t i = 0;
-        while (i < count && !isspace(data[i])) i++;
-
-        String_View result = { i, data };
-
-        count -= i;
-        data  += i;
-
-        return result;
-    }
-
-    template <typename Integer>
-    Maybe<Integer> from_hex() const
-    {
-        Integer result = {};
-
-        for (size_t i = 0; i < count; ++i) {
-            Integer x = data[i];
-            if ('0' <= x && x <= '9') {
-                x = (Integer) (x - '0');
-            } else if ('a' <= x && x <= 'f') {
-                x = (Integer) (x - 'a' + 10);
-            } else if ('A' <= x && x <= 'F') {
-                x = (Integer) (x - 'A' + 10);
-            } else {
-                return {};
-            }
-            result = result * (Integer) 0x10 + x;
-        }
-
-        return {true, result};
-    }
-
-    template <typename Integer>
-    Maybe<Integer> as_integer() const
-    {
-        Integer sign = 1;
-        Integer number = {};
-        String_View view = *this;
-
-        if (view.count == 0) {
-            return {};
-        }
-
-        if (*view.data == '-') {
-            sign = -1;
-            view.chop(1);
-        }
-
-        while (view.count) {
-            if (!isdigit(*view.data)) {
-                return {};
-            }
-            number = number * 10 + (*view.data - '0');
-            view.chop(1);
-        }
-
-        return { true, number * sign };
-    }
-
-    String_View subview(size_t start, size_t count) const
-    {
-        if (start + count <= this->count) {
-            return {count, data + start};
-        }
-
-        return {};
-    }
-
-    bool operator==(String_View view) const
-    {
-        if (this->count != view.count) return false;
-        return memcmp(this->data, view.data, this->count) == 0;
-    }
-
-    bool operator!=(String_View view) const
-    {
-        return !(*this == view);
-    }
-
-    bool has_prefix(String_View prefix) const
-    {
-        return prefix.count <= this->count
-            && this->subview(0, prefix.count) == prefix;
-    }
-};
-
-String_View cstr_as_string_view(const char *cstr)
-{
-    return {strlen(cstr), cstr};
-}
-
-const char *string_view_as_cstr(String_View s)
-{
-    char *cstr = new char[s.count + 1];
-    memcpy(cstr, s.data, s.count);
-    cstr[s.count] = '\0';
-    return cstr;
-}
-
-String_View operator ""_sv (const char *data, size_t count)
-{
-    String_View result;
-    result.count = count;
-    result.data = data;
-    return result;
-}
-
-void print1(FILE *stream, String_View view)
-{
-    fwrite(view.data, 1, view.count, stream);
-}
-
-String_View file_as_string_view(const char *filepath)
-{
-    assert(filepath);
-
-    size_t n = 0;
-    String_View result = {};
-    FILE *f = fopen(filepath, "rb");
-    if (!f) {
-        println(stderr, "Could not open file `", filepath, "`: ",
-                strerror(errno));
-        abort();
-    }
-
-    int code = fseek(f, 0, SEEK_END);
-    if (code < 0) {
-        println(stderr, "Could find the end of file ", filepath, ": ",
-                strerror(errno));
-        abort();
-    }
-
-    long m = ftell(f);
-    if (m < 0) {
-        println(stderr, "Could get the end of file ", filepath, ": ",
-                strerror(errno));
-        abort();
-    }
-    result.count = (size_t) m;
-
-    code = fseek(f, 0, SEEK_SET);
-    if (code < 0) {
-        println(stderr, "Could not find the beginning of file ", filepath, ": ",
-                strerror(errno));
-        abort();
-    }
-
-    char *buffer = new char[result.count];
-    if (!buffer) {
-        println(stderr, "Could not allocate memory for file ", filepath, ": ",
-                strerror(errno));
-        abort();
-    }
-
-    n = fread(buffer, 1, result.count, f);
-    if (n != result.count) {
-        println(stderr, "Could not read file ", filepath, ": ",
-                strerror(errno));
-        abort();
-    }
-
-    result.data = buffer;
-
-    return result;
-}
-
-// NOTE: stolen from http://www.cse.yorku.ca/~oz/hash.html
-unsigned long djb2(String_View str)
-{
-    unsigned long hash = 5381;
-    for (size_t i = 0; i < str.count; ++i) {
-        hash = ((hash << 5) + hash) + str.data[i];
-    }
-    return hash;
-}

+ 2 - 7
src/emote_downloader.cpp

@@ -13,13 +13,8 @@
 #include <curl/curl.h>
 #define TZOZEN_IMPLEMENTATION
 #include "./tzozen.h"
-#include "./core.cpp"
-
-template <typename T>
-T min(T a, T b)
-{
-    return a < b ? a : b;
-}
+#include "./aids.hpp"
+using namespace aids;
 
 template <typename T, size_t Capacity>
 struct Fixed_Array

+ 3 - 1
src/vodus.cpp

@@ -18,10 +18,12 @@ extern "C" {
 #include <libavutil/imgutils.h>
 }
 
+#include "./aids.hpp"
+using namespace aids;
+
 const size_t VODUS_MESSAGES_CAPACITY = 1024;
 
 // PLEASE READ THIS --> https://en.wikipedia.org/wiki/Single_Compilation_Unit
-#include "./core.cpp"
 #include "./vodus_image32.cpp"
 #include "./vodus_video_params.cpp"
 #include "./vodus_emotes.cpp"

+ 31 - 5
src/vodus_emotes.cpp

@@ -125,12 +125,21 @@ String_View file_extension(String_View filename)
     return ext;
 }
 
+const char *string_view_as_cstr(String_View sv)
+{
+    char *cstr = (char *) malloc(sv.count);
+    if (!cstr) return cstr;
+    memcpy(cstr, sv.data, sv.count);
+    return cstr;
+}
+
 Emote load_gif_emote(String_View file_path)
 {
     Emote emote = {Emote::Gif};
 
     auto file_path_cstr = string_view_as_cstr(file_path);
-    defer(delete[] file_path_cstr);
+    assert(file_path_cstr);
+    defer(free((void*) file_path_cstr));
 
     int error = 0;
     emote.gif.file_path = file_path;
@@ -149,7 +158,9 @@ Emote load_png_emote(String_View filepath)
 {
     Emote emote = {Emote::Png};
     auto filepath_cstr = string_view_as_cstr(filepath);
-    defer(delete[] filepath_cstr);
+    assert(filepath_cstr);
+    defer(free((void*) filepath_cstr));
+
     emote.png = load_image32_from_png(filepath_cstr);
     return emote;
 }
@@ -160,6 +171,16 @@ struct Emote_Mapping
     Emote emote;
 };
 
+// NOTE: stolen from http://www.cse.yorku.ca/~oz/hash.html
+unsigned long djb2(String_View str)
+{
+    unsigned long hash = 5381;
+    for (size_t i = 0; i < str.count; ++i) {
+        hash = ((hash << 5) + hash) + str.data[i];
+    }
+    return hash;
+}
+
 struct Emote_Cache
 {
     Maybe<Emote> emote_by_name(String_View name,
@@ -186,9 +207,14 @@ struct Emote_Cache
 
     void populate_from_file(const char *mapping_filepath)
     {
-        auto mapping_csv = file_as_string_view(mapping_filepath);
-        while (mapping_csv.count > 0 && emote_mapping_count < EMOTE_MAPPING_CAPACITY) {
-            auto line = mapping_csv.chop_by_delim('\n');
+        auto mapping_csv = read_file_as_string_view(mapping_filepath);
+        if (!mapping_csv.has_value) {
+            println(stderr, "Could not read file `", mapping_filepath, "`");
+            abort();
+        }
+
+        while (mapping_csv.unwrap.count > 0 && emote_mapping_count < EMOTE_MAPPING_CAPACITY) {
+            auto line = mapping_csv.unwrap.chop_by_delim('\n');
             auto name = line.chop_by_delim(',');
             auto filename = line;
             auto ext = file_extension(filename);

+ 12 - 8
src/vodus_main.cpp

@@ -451,10 +451,10 @@ Maybe<Pixel32> hexstr_as_pixel32(String_View hexstr)
     if (hexstr.count != 8) return {};
 
     Pixel32 result = {};
-    ASSIGN_UNWRAP(result.r, hexstr.subview(0, 2).from_hex<uint8_t>());
-    ASSIGN_UNWRAP(result.g, hexstr.subview(2, 2).from_hex<uint8_t>());
-    ASSIGN_UNWRAP(result.b, hexstr.subview(4, 2).from_hex<uint8_t>());
-    ASSIGN_UNWRAP(result.a, hexstr.subview(6, 2).from_hex<uint8_t>());
+    unwrap_into(result.r, hexstr.subview(0, 2).from_hex<uint8_t>());
+    unwrap_into(result.g, hexstr.subview(2, 2).from_hex<uint8_t>());
+    unwrap_into(result.b, hexstr.subview(4, 2).from_hex<uint8_t>());
+    unwrap_into(result.a, hexstr.subview(6, 2).from_hex<uint8_t>());
     return {true, result};
 }
 
@@ -685,16 +685,20 @@ int main(int argc, char *argv[])
         usage(stderr);
         exit(1);
     }
-    String_View input = file_as_string_view(log_filepath);
-    while (input.count > 0) {
+    auto input = read_file_as_string_view(log_filepath);
+    if (!input.has_value) {
+        println(stderr, "Could not read file `", log_filepath, "`");
+        abort();
+    }
+    while (input.unwrap.count > 0) {
         assert(messages_size < VODUS_MESSAGES_CAPACITY);
-        String_View message = input.chop_by_delim('\n');
+        String_View message = input.unwrap.chop_by_delim('\n');
         messages[messages_size].timestamp = (int) chop_timestamp(&message);
         messages[messages_size].nickname = chop_nickname(&message);
         messages[messages_size].message = message.trim();
         messages_size++;
     }
-    messages_size = std::min(messages_size, messages_limit);
+    messages_size = min(messages_size, messages_limit);
     std::sort(messages, messages + messages_size,
               [](const Message &m1, const Message &m2) {
                   return m1.timestamp < m2.timestamp;