ronantakizawa/codereview-bench huggingface dataset:
Repository: xbmc/xbmc
File: xbmc/guilib/GUIIncludes.cpp (C++)

Code before:
/*
 *  Copyright (C) 2005-2018 Team Kodi
 *  This file is part of Kodi - https://kodi.tv
 *
 *  SPDX-License-Identifier: GPL-2.0-or-later
 *  See LICENSES/README.md for more information.
 */

#include "GUIIncludes.h"

#include "GUIInfoManager.h"
#include "addons/Skin.h"
#include "guilib/GUIComponent.h"
#include "guilib/guiinfo/GUIInfoLabel.h"
#include "interfaces/info/SkinVariable.h"
#include "utils/StringUtils.h"
#include "utils/XBMCTinyXML.h"
#include "utils/XMLUtils.h"
#include "utils/log.h"

#include <algorithm>

using namespace KODI::GUILIB;

// Note: The following arrays must be sorted
static constexpr std::array<std::string_view, 17> constantAttributes = {
    "acceleration",
    "border",
    "center",
    "center",
    "delay",
    "end",
    "h",
    "height",
    "max",
    "min",
    "repeat",
    "start",
    "time",
    "w",
    "width",
    "x",
    "y",
};

static constexpr std::array<std::string_view, 35> constantNodes = {
    "bordersize",
    "bottom",
    "centerbottom",
    "centerleft",
    "centerright",

Review comment (suggestion):
Please change the name to `CONSTANT_ATTRIBUTES` according to our [Code Guidelines](https://github.com/xbmc/xbmc/blob/master/docs/CODE_GUIDELINES.md#82-constants). Same for the other constants.

Code after:
/*
 *  Copyright (C) 2005-2018 Team Kodi
 *  This file is part of Kodi - https://kodi.tv
 *
 *  SPDX-License-Identifier: GPL-2.0-or-later
 *  See LICENSES/README.md for more information.
 */

#include "GUIIncludes.h"

#include "GUIInfoManager.h"
#include "addons/Skin.h"
#include "guilib/GUIComponent.h"
#include "guilib/guiinfo/GUIInfoLabel.h"
#include "interfaces/info/SkinVariable.h"
#include "utils/StringUtils.h"
#include "utils/XBMCTinyXML.h"
#include "utils/XMLUtils.h"
#include "utils/log.h"

#include <algorithm>

using namespace KODI::GUILIB;

static constexpr std::array<std::string_view, 16> CONSTANT_ATTRIBUTES = {
    "acceleration", "border", "center", "delay", "end", "h",     "height", "max",
    "min",          "repeat", "start",  "time",  "w",   "width", "x",      "y",
};
static_assert(std::ranges::is_sorted(CONSTANT_ATTRIBUTES));

static constexpr std::array<std::string_view, 35> CONSTANT_NODES = {
    "bordersize",  "bottom",     "centerbottom",  "centerleft", "centerright", "centertop",
    "depth",       "fadetime",   "focusposition", "height",     "itemgap",     "left",
    "movement",    "offsetx",    "offsety",       "pauseatend", "posx",        "posy",
    "radioheight", "radioposx",  "radioposy",     "radiowidth", "right",       "sliderheight",
    "sliderwidth", "spinheight", "spinposx",      "spinposy",   "spinwidth",   "textoffsetx",
    "textoffsety", "textwidth",  "timeperimage",  "top",        "width",
};
static_assert(std::ranges::is_sorted(CONSTANT_NODES));

static constexpr std::string_view EXPRESSION_ATTRIBUTE = "condition";

static constexpr std::array<std::string_view, 4> EXPRESSION_NODES = {
    "enable",
    "selected",
    "usealttexture",
    "visible",
};
static_assert(std::ranges::is_sorted(EXPRESSION_NODES));

CGUIIncludes::CGUIIncludes() = default;
Repository: xbmc/xbmc
File: xbmc/guilib/GUIIncludes.cpp (C++)

Code before:
 *  This file is part of Kodi - https://kodi.tv
 *
 *  SPDX-License-Identifier: GPL-2.0-or-later
 *  See LICENSES/README.md for more information.
 */

#include "GUIIncludes.h"

#include "GUIInfoManager.h"
#include "addons/Skin.h"
#include "guilib/GUIComponent.h"
#include "guilib/guiinfo/GUIInfoLabel.h"
#include "interfaces/info/SkinVariable.h"
#include "utils/StringUtils.h"
#include "utils/XBMCTinyXML.h"
#include "utils/XMLUtils.h"
#include "utils/log.h"

#include <algorithm>

using namespace KODI::GUILIB;

// Note: The following arrays must be sorted
static constexpr std::array<std::string_view, 17> constantAttributes = {
    "acceleration",
    "border",
    "center",
    "center",
    "delay",
    "end",
    "h",
    "height",
    "max",
    "min",
    "repeat",
    "start",
    "time",
    "w",
    "width",
    "x",
    "y",
};

static constexpr std::array<std::string_view, 35> constantNodes = {
    "bordersize",
    "bottom",
    "centerbottom",
    "centerleft",
    "centerright",
    "centertop",
    "depth",

Review comment (suggestion):
It should be checked at compile time that the arrays are sorted correctly:
```cpp
static_assert(std::ranges::is_sorted(constantAttributes));
```

Code after:
 *  This file is part of Kodi - https://kodi.tv
 *
 *  SPDX-License-Identifier: GPL-2.0-or-later
 *  See LICENSES/README.md for more information.
 */

#include "GUIIncludes.h"

#include "GUIInfoManager.h"
#include "addons/Skin.h"
#include "guilib/GUIComponent.h"
#include "guilib/guiinfo/GUIInfoLabel.h"
#include "interfaces/info/SkinVariable.h"
#include "utils/StringUtils.h"
#include "utils/XBMCTinyXML.h"
#include "utils/XMLUtils.h"
#include "utils/log.h"

#include <algorithm>

using namespace KODI::GUILIB;

static constexpr std::array<std::string_view, 16> CONSTANT_ATTRIBUTES = {
    "acceleration", "border", "center", "delay", "end", "h",     "height", "max",
    "min",          "repeat", "start",  "time",  "w",   "width", "x",      "y",
};
static_assert(std::ranges::is_sorted(CONSTANT_ATTRIBUTES));

static constexpr std::array<std::string_view, 35> CONSTANT_NODES = {
    "bordersize",  "bottom",     "centerbottom",  "centerleft", "centerright", "centertop",
    "depth",       "fadetime",   "focusposition", "height",     "itemgap",     "left",
    "movement",    "offsetx",    "offsety",       "pauseatend", "posx",        "posy",
    "radioheight", "radioposx",  "radioposy",     "radiowidth", "right",       "sliderheight",
    "sliderwidth", "spinheight", "spinposx",      "spinposy",   "spinwidth",   "textoffsetx",
    "textoffsety", "textwidth",  "timeperimage",  "top",        "width",
};
static_assert(std::ranges::is_sorted(CONSTANT_NODES));

static constexpr std::string_view EXPRESSION_ATTRIBUTE = "condition";

static constexpr std::array<std::string_view, 4> EXPRESSION_NODES = {
    "enable",
    "selected",
    "usealttexture",
    "visible",
};
static_assert(std::ranges::is_sorted(EXPRESSION_NODES));

CGUIIncludes::CGUIIncludes() = default;

CGUIIncludes::~CGUIIncludes() = default;
Repository: xbmc/xbmc
File: xbmc/guilib/GUIIncludes.h (C/C++)

Code before:
/*
 *  Copyright (C) 2005-2018 Team Kodi
 *  This file is part of Kodi - https://kodi.tv
 *
 *  SPDX-License-Identifier: GPL-2.0-or-later
 *  See LICENSES/README.md for more information.
 */

#pragma once

#include "interfaces/info/InfoBool.h"

#include <map>
#include <string>
#include <unordered_map>
#include <vector>

// forward definitions
class TiXmlElement;
namespace INFO
{
  class CSkinVariableString;
}

class CGUIIncludes
{
public:
  CGUIIncludes();
  ~CGUIIncludes();

  /*!
   \brief Clear all include components (defaults, constants, variables, expressions and includes)
  */
  void Clear();

  /*!
   \brief Load all include components(defaults, constants, variables, expressions and includes)
   from the main entrypoint \code{file}. Flattens nested expressions and expressions in variable
   conditions after loading all other included files.

   \param file the file to load
  */

Review comment (refactor):
Adding back the `<utility>` header for `std::pair` should make Jenkins happy.

Code after:
/*
 *  Copyright (C) 2005-2018 Team Kodi
 *  This file is part of Kodi - https://kodi.tv
 *
 *  SPDX-License-Identifier: GPL-2.0-or-later
 *  See LICENSES/README.md for more information.
 */

#pragma once

#include "interfaces/info/InfoBool.h"

#include <map>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>

#include <tinyxml.h>

// forward definitions
namespace INFO
{
  class CSkinVariableString;
}

class CGUIIncludes
{
public:
  CGUIIncludes();
  ~CGUIIncludes();

  /*!
   \brief Clear all include components (defaults, constants, variables, expressions and includes)
  */
  void Clear();

  /*!
   \brief Load all include components(defaults, constants, variables, expressions and includes)
   from the main entrypoint \code{file}. Flattens nested expressions and expressions in variable
   conditions after loading all other included files.
Repository: xbmc/xbmc
File: xbmc/utils/XSLTUtils.cpp (C++)

Code before:
bool XSLTUtils::SetInput(const std::string& input)
{
  m_xmlInput = xmlParseMemory(input.c_str(), input.size());
  if (!m_xmlInput)
    return false;
  return true;
}

bool XSLTUtils::SetStylesheet(const std::string& stylesheet)
{
  if (m_xsltStylesheet) {
    xsltFreeStylesheet(m_xsltStylesheet);
    m_xsltStylesheet = NULL;
  }

  m_xmlStylesheet = xmlParseMemory(stylesheet.c_str(), stylesheet.size());
  if (!m_xmlStylesheet)
  {
    CLog::Log(LOGDEBUG, "could not xmlParseMemory stylesheetdoc");
    return false;
  }

  m_xsltStylesheet = xsltParseStylesheetDoc(m_xmlStylesheet);
  if (!m_xsltStylesheet) {
    CLog::Log(LOGDEBUG, "could not parse stylesheetdoc");
    xmlFree(m_xmlStylesheet);
    m_xmlStylesheet = NULL;
    return false;
  }

  return true;
}


Review comment (bug):
Consider enhancing the error message for clarity by adding a space (e.g., "could not read stylesheet doc").
```suggestion
    CLog::Log(LOGDEBUG, "could not read stylesheet doc");
```

Code after:
  return true;
}

bool XSLTUtils::SetInput(const std::string& input)
{
  m_xmlInput = xmlReadMemory(input.c_str(), input.size(), NULL, NULL, XML_PARSE_NOENT);

  if (!m_xmlInput)
    return false;
  return true;
}

bool XSLTUtils::SetStylesheet(const std::string& stylesheet)
{
  if (m_xsltStylesheet) {
    xsltFreeStylesheet(m_xsltStylesheet);
    m_xsltStylesheet = NULL;
  }

  m_xmlStylesheet =
      xmlReadMemory(stylesheet.c_str(), stylesheet.size(), NULL, NULL, XML_PARSE_NOENT);

  if (!m_xmlStylesheet)
  {
    CLog::Log(LOGDEBUG, "could not read stylesheetdoc");
    return false;
  }

  m_xsltStylesheet = xsltParseStylesheetDoc(m_xmlStylesheet);
  if (!m_xsltStylesheet) {
    CLog::Log(LOGDEBUG, "could not parse stylesheetdoc");
    xmlFree(m_xmlStylesheet);
    m_xmlStylesheet = NULL;
    return false;
  }

  return true;
}
Repository: xbmc/xbmc
File: xbmc/utils/DiscsUtils.cpp (C++)

Code before:
#ifdef HAVE_LIBBLURAY
  XFILE::CBlurayDirectory bdDir;
  if (!bdDir.InitializeBluray(mediaPath))
    return info;

  info.type = DiscType::BLURAY;
  info.name = bdDir.GetBlurayTitle();
  info.serial = bdDir.GetBlurayID();
#endif
  return info;
}

bool UTILS::DISCS::IsBlurayDiscImage(const CFileItem& item)
{
  if (!item.IsDiscImage())
    return false;

  constexpr std::array<const char*, 4> blurayFiles = {
      "index.bdmv",
      "INDEX.BDM",
      "BDMV/index.bdmv",
      "BDMV/INDEX.BDM",
  };
  const std::string& path{item.GetDynPath()};
  CURL url("udf://");
  url.SetHostName(path);

  return std::ranges::any_of(blurayFiles,
                             [&url](const std::string& file)
                             {
                               url.SetFileName(file);
                               return XFILE::CFile::Exists(url.Get());
                             });
}


Review comment (suggestion):
shorter:

```c++
  CURL url("udf://");
  url.SetHostName(item.GetDynPath());
```

Code after:
#ifdef HAVE_LIBBLURAY
  XFILE::CBlurayDirectory bdDir;
  if (!bdDir.InitializeBluray(mediaPath))
    return info;

  info.type = DiscType::BLURAY;
  info.name = bdDir.GetBlurayTitle();
  info.serial = bdDir.GetBlurayID();
#endif
  return info;
}

bool UTILS::DISCS::IsBlurayDiscImage(const CFileItem& item)
{
  if (!item.IsDiscImage())
    return false;

  static constexpr std::array<std::string_view, 4> blurayFiles = {
      "index.bdmv",
      "INDEX.BDM",
      "BDMV/index.bdmv",
      "BDMV/INDEX.BDM",
  };
  CURL url("udf://");
  url.SetHostName(item.GetDynPath());

  return std::ranges::any_of(blurayFiles,
                             [&url](std::string_view file)
                             {
                               url.SetFileName(std::string(file));
                               return XFILE::CFile::Exists(url.Get());
                             });
}
Repository: xbmc/xbmc
File: xbmc/utils/DiscsUtils.cpp (C++)

Code before:
  info.name = bdDir.GetBlurayTitle();
  info.serial = bdDir.GetBlurayID();
#endif
  return info;
}

bool UTILS::DISCS::IsBlurayDiscImage(const CFileItem& item)
{
  if (!item.IsDiscImage())
    return false;

  static constexpr std::array<const char*, 4> blurayFiles = {
      "index.bdmv",
      "INDEX.BDM",
      "BDMV/index.bdmv",
      "BDMV/INDEX.BDM",
  };
  CURL url("udf://");
  url.SetHostName(item.GetDynPath());

  return std::ranges::any_of(blurayFiles,
                             [&url](const std::string& file)
                             {
                               url.SetFileName(file);
                               return XFILE::CFile::Exists(url.Get());
                             });
}


Review comment (suggestion):
```suggestion
  return std::ranges::any_of(blurayFiles,
                             [&url](std::string_view file)
                             {
                               url.SetFileName(file);
                               return XFILE::CFile::Exists(url.Get());
                             });
```
If you use a `const std::string&` as the parameter here you have to construct two `std::string` per `blurayFiles` element: One to pass into the function and one copy to pass into `url.SetFileName(file)`. With the `std::string_view` parameter the first creation can be omitted.

Code after:
  info.name = bdDir.GetBlurayTitle();
  info.serial = bdDir.GetBlurayID();
#endif
  return info;
}

bool UTILS::DISCS::IsBlurayDiscImage(const CFileItem& item)
{
  if (!item.IsDiscImage())
    return false;

  static constexpr std::array<std::string_view, 4> blurayFiles = {
      "index.bdmv",
      "INDEX.BDM",
      "BDMV/index.bdmv",
      "BDMV/INDEX.BDM",
  };
  CURL url("udf://");
  url.SetHostName(item.GetDynPath());

  return std::ranges::any_of(blurayFiles,
                             [&url](std::string_view file)
                             {
                               url.SetFileName(std::string(file));
                               return XFILE::CFile::Exists(url.Get());
                             });
}
Repository: xbmc/xbmc
File: xbmc/video/windows/GUIWindowVideoBase.cpp (C++)

Code before:
    const int itemNumber{m_viewControl.GetSelectedItem()};
    Refresh();
    m_viewControl.SetSelectedItem(itemNumber);
  }

  return ret;
}

void CGUIWindowVideoBase::OnQueueItem(int iItem, bool first)
{
  if (iItem < 0 || iItem >= m_vecItems->Size())
    return;

  OnQueueItem(m_vecItems->Get(iItem), iItem, first);
}

void CGUIWindowVideoBase::OnQueueItem(const std::shared_ptr<CFileItem>& item, int iItem, bool first)
{
  // don't re-queue items from playlist window
  if (GetID() == WINDOW_VIDEO_PLAYLIST)
    return;

  if (item->IsRAR() || item->IsZIP())
    return;

  VIDEO::UTILS::QueueItem(item, first ? VIDEO::UTILS::QueuePosition::POSITION_BEGIN
                                      : VIDEO::UTILS::QueuePosition::POSITION_END);

  // select next item
  m_viewControl.SetSelectedItem(iItem + 1);
}

namespace
{
class CVideoPlayActionProcessor : public VIDEO::GUILIB::CVideoPlayActionProcessor
{
public:
  CVideoPlayActionProcessor(CGUIWindowVideoBase& window,
                            const std::shared_ptr<CFileItem>& item,
                            const std::string& player)
    : VIDEO::GUILIB::CVideoPlayActionProcessor(item), m_window(window), m_player(player)
  {
  }

protected:
  bool OnResumeSelected() override { return m_window.PlayItem(m_item, m_player); }

  bool OnPlaySelected() override { return m_window.PlayItem(m_item, m_player); }

private:
  CGUIWindowVideoBase& m_window;

Review comment (suggestion):
[nitpick] If all enum cases for ShowInfoResult are explicitly handled in the switch, consider either removing the default branch or adding a comment to clarify its inclusion for future maintainers.

Code after:
  const ShowInfoResult result{ShowInfo(item, info)};
  switch (result)
  {
    using enum ShowInfoResult;

    case RESULT_ERROR:
      return false;
    case RESULT_OK_NOT_UPDATED:
      return true;
    case RESULT_OK_UPDATED:
    {
      // Test IsActive() since we can be called from other windows (music, home) we need this check
      if (IsActive())
      {
        const int selectedItem{m_viewControl.GetSelectedItem()};
        Refresh();
        m_viewControl.SetSelectedItem(selectedItem);
      }
      return true;
    }
    default:
      break;
  }

  CLog::LogF(LOGWARNING, "Unhandled ShowInfoResult value treated as error.");
  return false;
}

void CGUIWindowVideoBase::OnQueueItem(int iItem, bool first)
{
  if (iItem < 0 || iItem >= m_vecItems->Size())
    return;

  OnQueueItem(m_vecItems->Get(iItem), iItem, first);
}

void CGUIWindowVideoBase::OnQueueItem(const std::shared_ptr<CFileItem>& item, int iItem, bool first)
{
  // don't re-queue items from playlist window
  if (GetID() == WINDOW_VIDEO_PLAYLIST)
    return;

  if (item->IsRAR() || item->IsZIP())
    return;

  VIDEO::UTILS::QueueItem(item, first ? VIDEO::UTILS::QueuePosition::POSITION_BEGIN
                                      : VIDEO::UTILS::QueuePosition::POSITION_END);

  // select next item
  m_viewControl.SetSelectedItem(iItem + 1);
}
Repository: xbmc/xbmc
File: xbmc/FileItemList.cpp (C++)

Code before:
{
  std::unique_lock<CCriticalSection> lock(m_lock);

  if (iItem > -1 && iItem < static_cast<int>(m_items.size()))
    return m_items[iItem];

  return CFileItemPtr();
}

CFileItemPtr CFileItemList::Get(const std::string& strPath) const
{
  std::unique_lock<CCriticalSection> lock(m_lock);

  if (m_fastLookup)
  {
    const auto it = m_map.find(m_ignoreURLOptions ? CURL(strPath).GetWithoutOptions() : strPath);
    if (it != m_map.end())
      return it->second;

    return CFileItemPtr();
  }
  // slow method...
  const std::string fname = m_ignoreURLOptions ? CURL(strPath).GetWithoutOptions() : strPath;
  const auto it = std::ranges::find_if(m_items, [&fname](const auto& pItem) { return pItem->IsPath(fname); });
  return it != m_items.end() ? *it : CFileItemPtr();
}

int CFileItemList::Size() const
{
  std::unique_lock<CCriticalSection> lock(m_lock);
  return static_cast<int>(m_items.size());
}

bool CFileItemList::IsEmpty() const
{
  std::unique_lock<CCriticalSection> lock(m_lock);
  return m_items.empty();
}

void CFileItemList::Reserve(size_t iCount)
{
  std::unique_lock<CCriticalSection> lock(m_lock);
  m_items.reserve(iCount);
}

void CFileItemList::Sort(SortBy sortBy,
                         SortOrder sortOrder,
                         SortAttribute sortAttributes /* = SortAttributeNone */)
{
  if (sortBy == SortByNone ||
      (m_sortDescription.sortBy == sortBy && m_sortDescription.sortOrder == sortOrder &&

Review comment (suggestion):
I think you can do

```c++
return it != m_items.end() ? *it : {};
```

Saves an extra reference to an unnecessary-to-begin-with typedef.

Code after:
{
  std::unique_lock<CCriticalSection> lock(m_lock);

  if (iItem > -1 && iItem < static_cast<int>(m_items.size()))
    return m_items[iItem];

  return CFileItemPtr();
}

CFileItemPtr CFileItemList::Get(const std::string& strPath) const
{
  std::unique_lock<CCriticalSection> lock(m_lock);

  if (m_fastLookup)
  {
    const auto it = m_map.find(m_ignoreURLOptions ? CURL(strPath).GetWithoutOptions() : strPath);
    if (it != m_map.end())
      return it->second;

    return CFileItemPtr();
  }
  // slow method...
  const std::string fname = m_ignoreURLOptions ? CURL(strPath).GetWithoutOptions() : strPath;
  const auto it =
      std::ranges::find_if(m_items, [&fname](const auto& pItem) { return pItem->IsPath(fname); });
  return it != m_items.end() ? *it : CFileItemPtr();
}

int CFileItemList::Size() const
{
  std::unique_lock<CCriticalSection> lock(m_lock);
  return static_cast<int>(m_items.size());
}

bool CFileItemList::IsEmpty() const
{
  std::unique_lock<CCriticalSection> lock(m_lock);
  return m_items.empty();
}

void CFileItemList::Reserve(size_t iCount)
{
  std::unique_lock<CCriticalSection> lock(m_lock);
  m_items.reserve(iCount);
}

void CFileItemList::Sort(SortBy sortBy,
                         SortOrder sortOrder,
                         SortAttribute sortAttributes /* = SortAttributeNone */)
{
  if (sortBy == SortByNone ||
Repository: xbmc/xbmc
File: xbmc/utils/log.cpp (C++)

Code before:
    case LOGWARNING:
      return spdlog::level::warn;
    case LOGERROR:
      return spdlog::level::err;
    case LOGFATAL:
      return spdlog::level::critical;
    case LOGNONE:
      return spdlog::level::off;

    default:
      break;
  }

  return spdlog::level::info;
}

void CLog::FormatAndLogInternal(spdlog::level::level_enum level,
                                fmt::string_view format,
                                fmt::format_args args)
{
  if (level < m_defaultLogger->level())
    return;

  auto message = fmt::vformat(format, args);

  // fixup newline alignment, number of spaces should equal prefix length
  FormatLineBreaks(message);

  m_defaultLogger->log(level, message);
}

Logger CLog::CreateLogger(const std::string& loggerName)
{
  // create the logger
  auto logger = std::make_shared<spdlog::logger>(loggerName, m_sinks);

  // initialize the logger
  spdlog::initialize_logger(logger);

  return logger;
}

void CLog::SetComponentLogLevel(const std::vector<CVariant>& components)
{
  m_componentLogLevels = 0;
  for (const auto& component : components)
  {
    if (!component.isInteger())
      continue;

    m_componentLogLevels |= static_cast<uint32_t>(component.asInteger());

Review comment (refactor):
`FormatLineBreaks()` only is used here, then maybe remove this method and call directly:

`StringUtils::Replace(message, "\n", "\n                                                   ");` 




Code after:
      return spdlog::level::warn;
    case LOGERROR:
      return spdlog::level::err;
    case LOGFATAL:
      return spdlog::level::critical;
    case LOGNONE:
      return spdlog::level::off;

    default:
      break;
  }

  return spdlog::level::info;
}

void CLog::FormatAndLogInternal(spdlog::level::level_enum level,
                                fmt::string_view format,
                                fmt::format_args args)
{
  if (level < m_defaultLogger->level())
    return;

  auto message = fmt::vformat(format, args);

  // fixup newline alignment, number of spaces should equal prefix length
  FormatLineBreaks(message);

  m_defaultLogger->log(level, message);
}

Logger CLog::CreateLogger(const std::string& loggerName)
{
  // create the logger
  auto logger = std::make_shared<spdlog::logger>(loggerName, m_sinks);

  // initialize the logger
  spdlog::initialize_logger(logger);

  return logger;
}

void CLog::SetComponentLogLevel(const std::vector<CVariant>& components)
{
  m_componentLogLevels = 0;
  for (const auto& component : components)
  {
    if (!component.isInteger())
      continue;

    m_componentLogLevels |= static_cast<uint32_t>(component.asInteger());
  }