ronantakizawa/codereview-bench huggingface dataset:
Repository: xbmc/xbmc
File: xbmc/cores/AudioEngine/Sinks/AESinkWASAPI.cpp (C++)

Code before:
const IID IID_IAudioClock = __uuidof(IAudioClock);
DEFINE_PROPERTYKEY(PKEY_Device_FriendlyName, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 14);
DEFINE_PROPERTYKEY(PKEY_Device_EnumeratorName, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 24);

#define EXIT_ON_FAILURE(hr, reason) \
  if (FAILED(hr)) \
  { \
    CLog::LogF(LOGERROR, reason " - error {}", hr, CWIN32Util::FormatHRESULT(hr)); \
    goto failed; \
  }

template<class T>
inline void SafeRelease(T **ppT)
{
  if (*ppT)
  {
    (*ppT)->Release();
    *ppT = nullptr;
  }
}

using namespace Microsoft::WRL;
using namespace std::chrono_literals;

constexpr auto minPcmBufferDuration = 20ms;
constexpr auto minPassthroughBufferDuration = 50ms;

CAESinkWASAPI::CAESinkWASAPI()
{
  m_channelLayout.Reset();

  // Get performance counter frequency for latency calculations
  QueryPerformanceFrequency(&m_timerFreq);
}

CAESinkWASAPI::~CAESinkWASAPI()
{
}

void CAESinkWASAPI::Register()
{
  AE::AESinkRegEntry reg;
  reg.sinkName = "WASAPI";
  reg.createFunc = CAESinkWASAPI::Create;
  reg.enumerateFunc = CAESinkWASAPI::EnumerateDevicesEx;
  AE::CAESinkFactory::RegisterSink(reg);
}

std::unique_ptr<IAESink> CAESinkWASAPI::Create(std::string& device, AEAudioFormat& desiredFormat)
{
  auto sink = std::make_unique<CAESinkWASAPI>();

Review comment (suggestion):
Maybe rename to `minPcmPeriod` and `minPassthroughPeriod` shorter variables names avoids some line breaks.

Also define inside namespace.

Code after:
{
constexpr auto minPcmPeriod{20ms};
constexpr auto minPassthroughPeriod{50ms};
} // namespace

const IID IID_IAudioRenderClient = __uuidof(IAudioRenderClient);
const IID IID_IAudioClock = __uuidof(IAudioClock);
DEFINE_PROPERTYKEY(PKEY_Device_FriendlyName, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 14);
DEFINE_PROPERTYKEY(PKEY_Device_EnumeratorName, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 24);

#define EXIT_ON_FAILURE(hr, reason) \
  if (FAILED(hr)) \
  { \
    CLog::LogF(LOGERROR, reason " - error {}", hr, CWIN32Util::FormatHRESULT(hr)); \
    goto failed; \
  }

template<class T>
inline void SafeRelease(T **ppT)
{
  if (*ppT)
  {
    (*ppT)->Release();
    *ppT = nullptr;
  }
}

CAESinkWASAPI::CAESinkWASAPI()
{
  m_channelLayout.Reset();

  // Get performance counter frequency for latency calculations
  QueryPerformanceFrequency(&m_timerFreq);
}

CAESinkWASAPI::~CAESinkWASAPI()
{
}

void CAESinkWASAPI::Register()
{
  AE::AESinkRegEntry reg;
  reg.sinkName = "WASAPI";
  reg.createFunc = CAESinkWASAPI::Create;
  reg.enumerateFunc = CAESinkWASAPI::EnumerateDevicesEx;
  AE::CAESinkFactory::RegisterSink(reg);
}

std::unique_ptr<IAESink> CAESinkWASAPI::Create(std::string& device, AEAudioFormat& desiredFormat)
{
  auto sink = std::make_unique<CAESinkWASAPI>();
Repository: xbmc/xbmc
File: xbmc/cores/AudioEngine/Sinks/AESinkWASAPI.cpp (C++)

Code before:
  CLog::Log(LOGDEBUG, "  Format cBSize   : {}", wfxex.Format.cbSize);
  CLog::Log(LOGDEBUG, "  Channel Layout  : {}", ((std::string)format.m_channelLayout));
  CLog::Log(LOGDEBUG, "  Channel Mask    : {}", wfxex.dwChannelMask);
  CLog::Log(LOGDEBUG, "  Frames          : {}", m_uiBufferLen);
  CLog::Log(LOGDEBUG, "  Frame Size      : {}", format.m_frameSize);
  CLog::Log(LOGDEBUG, "  Periodicity (ms): {:.1f}", (float)audioSinkBufferDurationMsec / 10000.0f);
  CLog::Log(LOGDEBUG, "  Latency (s)     : {:.3f}", m_sinkLatency);

  return true;
}

void CAESinkWASAPI::Drain()
{
  if(!m_pAudioClient)
    return;

  if (WriteLastBuffer())
  {
    // wait for last data in buffer to play before stopping
    // current buffer + WriteLastBuffer (two buffers same as m_sinkLatency)
    KODI::TIME::Sleep(std::chrono::milliseconds(static_cast<int>(m_sinkLatency * 1000)));
  }
  else
  {
    // wait for last data in buffer to play before stopping (current buffer only)
    KODI::TIME::Sleep(std::chrono::milliseconds(static_cast<int>(m_sinkLatency / 2 * 1000)));
  }

  if (m_running)
  {
    try
    {
      m_pAudioClient->Stop();  //stop the audio output
      m_pAudioClient->Reset(); //flush buffer and reset audio clock stream position
      m_sinkFrames = 0;
    }
    catch (...)
    {
      CLog::LogF(LOGDEBUG, "Invalidated AudioClient - Releasing");
    }
  }
  m_running = false;
}

bool CAESinkWASAPI::WriteLastBuffer()
{
  if (!m_initialized || !m_running)
    return false;

  // complete pending m_buffer with silence or generate one new m_buffer of silence
  uint8_t* buffer = m_buffer.data();

Review comment (performance):
Can `m_sinkLatency` be odd? Maybe should be `m_sinkLatency * 1000 / 2`?

Code after:

  return true;
}

void CAESinkWASAPI::Drain()
{
  if(!m_pAudioClient)
    return;

  WriteLastBuffer();

  // Wait for last data in buffer to play before stopping (current buffer + WriteLastBuffer).
  // If WriteLastBuffer() fails, it doesn't matter wait for the time of two buffers anyway.
  KODI::TIME::Sleep(std::chrono::milliseconds(static_cast<int>(m_sinkLatency * 1000)));

  if (m_running)
  {
    try
    {
      m_pAudioClient->Stop();  //stop the audio output
      m_pAudioClient->Reset(); //flush buffer and reset audio clock stream position
      m_sinkFrames = 0;
    }
    catch (...)
    {
      CLog::LogF(LOGDEBUG, "Invalidated AudioClient - Releasing");
    }
  }
  m_running = false;
}

void CAESinkWASAPI::WriteLastBuffer()
{
  if (!m_initialized || !m_running)
    return;

  // complete pending m_buffer with silence or generate one new m_buffer of silence
  uint8_t* buffer = m_buffer.data();
  unsigned int frames = m_format.m_frames;
  if (m_bufferPtr != 0)
  {
    frames = m_format.m_frames - m_bufferPtr;
    buffer += m_bufferPtr * m_format.m_frameSize;
  }
  CAEUtil::GenerateSilence(m_format.m_dataFormat, m_format.m_frameSize, buffer, frames);

  LARGE_INTEGER timerStart{};
  QueryPerformanceCounter(&timerStart);

  // wait for buffer available
  if (WaitForSingleObject(m_needDataEvent, 1100) != WAIT_OBJECT_0)
Repository: xbmc/xbmc
File: xbmc/platform/win32/threads/ThreadImplWin.cpp (C++)

Code before:
/*
 *  Copyright (C) 2005-2026 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 "ThreadImplWin.h"

#include "CharsetConverter.h"
#include "utils/Map.h"
#include "utils/log.h"

#include "platform/win32/WIN32Util.h"

#include <array>
#include <mutex>
#include <string>
#include <string_view>

#ifdef TARGET_WINDOWS_DESKTOP
#include <avrt.h>
#endif
#include <process.h>
#include <processthreadsapi.h>
#include <windows.h>

namespace
{

struct NativeThreadPriority
{
  int priority;
  std::string_view name;
};

Review comment (suggestion):
Seems this should be `#include "platform/win32/CharsetConverter.h"`

Code after:
/*
 *  Copyright (C) 2005-2026 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 "ThreadImplWin.h"

#include "utils/Map.h"
#include "utils/log.h"

#include "platform/win32/CharsetConverter.h"
#include "platform/win32/WIN32Util.h"

#include <array>
#include <mutex>
#include <string_view>

#ifdef TARGET_WINDOWS_DESKTOP
#include <avrt.h>
#endif
#include <process.h>
#include <processthreadsapi.h>
#include <windows.h>

namespace
{

struct NativeThreadPriority
{
  int priority;
  std::string_view name;
};
Repository: xbmc/xbmc
File: xbmc/platform/win32/threads/ThreadImplWin.cpp (C++)

Code before:
  {
    return it->second;
  }
  else
  {
    throw std::range_error("Priority not found");
  }
}

void LogProcessPriorityClass()
{
  const DWORD prioClass = GetPriorityClass(GetCurrentProcess());

  if (prioClass == 0)
  {
    CLog::LogF(LOGERROR, "unable to retrieve the process priority class ({})", GetLastError());
    return;
  }

  if (const auto it = priorityClasses.find(prioClass); it != priorityClasses.end())
    CLog::Log(LOGDEBUG, "[threads] app priority: {}", it->second);
  else
    CLog::Log(LOGDEBUG, "[threads] app priority: unrecognized (0x{:08X})", prioClass);
}

std::string ThreadTaskToNativeTask(ThreadTask task)
{
  if (task == ThreadTask::AUDIO)
    return "Audio";
  else
    throw std::range_error("Task not found");
}

std::once_flag flag;

} // namespace

std::unique_ptr<IThreadImpl> IThreadImpl::CreateThreadImpl(std::thread::native_handle_type handle)
{
  return std::make_unique<CThreadImplWin>(handle);
}

CThreadImplWin::CThreadImplWin(std::thread::native_handle_type handle) : IThreadImpl(handle)
{
}

void CThreadImplWin::SetThreadInfo(const std::string& name)
{
  // Modern way to name threads first (Windows 10 1607 and above)
  if (!CWIN32Util::SetThreadName(static_cast<HANDLE>(m_handle), name))
  {

Review comment (suggestion):
```suggestion
const std::string ThreadTaskToNativeTask(ThreadTask task)
```

Code after:
    return it->second;
  }
  else
  {
    throw std::range_error("Priority not found");
  }
}

void LogProcessPriorityClass()
{
  const DWORD prioClass = GetPriorityClass(GetCurrentProcess());

  if (prioClass == 0)
  {
    CLog::LogF(LOGERROR, "unable to retrieve the process priority class ({})", GetLastError());
    return;
  }

  if (const auto it = priorityClasses.find(prioClass); it != priorityClasses.end())
    CLog::Log(LOGDEBUG, "[threads] app priority: {}", it->second);
  else
    CLog::Log(LOGDEBUG, "[threads] app priority: unrecognized (0x{:08X})", prioClass);
}

constexpr std::string_view ThreadTaskToNativeTask(ThreadTask task)
{
  if (task == ThreadTask::AUDIO)
    return "Audio";
  else
    throw std::range_error("Task not found");
}

std::once_flag flag;

} // namespace

std::unique_ptr<IThreadImpl> IThreadImpl::CreateThreadImpl(std::thread::native_handle_type handle)
{
  return std::make_unique<CThreadImplWin>(handle);
}

CThreadImplWin::CThreadImplWin(std::thread::native_handle_type handle) : IThreadImpl(handle)
{
}

void CThreadImplWin::SetThreadInfo(const std::string& name)
{
  // Modern way to name threads first (Windows 10 1607 and above)
  if (!CWIN32Util::SetThreadName(static_cast<HANDLE>(m_handle), name))
  {
    // Fallback on legacy method - specially configured exception
Repository: xbmc/xbmc
File: xbmc/platform/win32/threads/ThreadImplWin.cpp (C++)

Code before:

  std::unique_lock lock(m_criticalSection);
  if (m_handle)
  {
    const NativeThreadPriority native = ThreadPriorityToNativePriority(priority);

    if (SetThreadPriority(m_handle, native.priority) == 0)
    {
      CLog::LogF(LOGERROR, "unable to set the priority of thread {} ({})", m_name, GetLastError());
      bReturn = false;
    }
    else
    {
      CLog::Log(LOGDEBUG, "[threads] name: '{}' priority: {}", m_name, native.name);
      bReturn = true;
    }
  }
  return bReturn;
}

bool CThreadImplWin::SetTask(const ThreadTask& task)
{
#ifdef TARGET_WINDOWS_DESKTOP
  std::call_once(flag, LogProcessPriorityClass);

  const std::string taskName{ThreadTaskToNativeTask(task)};

  using namespace KODI::PLATFORM::WINDOWS;

  m_hTask = AvSetMmThreadCharacteristicsW(ToW(taskName).c_str(), &m_taskIndex);
  if (m_hTask == 0)
  {
    CLog::LogF(LOGERROR, "unable to register thread with the multimedia scheduler ({})",
               GetLastError());
    return false;
  }

  CLog::Log(LOGDEBUG, "[threads] name: '{}' task: {}", m_name, taskName);
#endif
  return true;
}

bool CThreadImplWin::RevertTask()
{
  bool ret{true};
#ifdef TARGET_WINDOWS_DESKTOP
  std::call_once(flag, LogProcessPriorityClass);

  if (m_hTask != 0)
  {
    if (AvRevertMmThreadCharacteristics(m_hTask) == 0)

Review comment (suggestion):
```suggestion
  const std::string& taskName = ThreadTaskToNativeTask(task);
```

To avoid create a copy of string.

Is similar case of:
https://github.com/xbmc/xbmc/blob/c21744d2915dbb3f3c34da0d86741d45a0ae6435/xbmc/settings/ServicesSettings.cpp#L21-L22 
And many other places.

Code after:
  std::unique_lock lock(m_criticalSection);
  if (m_handle)
  {
    const NativeThreadPriority native = ThreadPriorityToNativePriority(priority);

    if (SetThreadPriority(m_handle, native.priority) == 0)
    {
      CLog::LogF(LOGERROR, "unable to set the priority of thread {} ({})", m_name, GetLastError());
      bReturn = false;
    }
    else
    {
      CLog::Log(LOGDEBUG, "[threads] name: '{}' priority: {}", m_name, native.name);
      bReturn = true;
    }
  }
  return bReturn;
}

bool CThreadImplWin::SetTask(const ThreadTask& task)
{
#ifdef TARGET_WINDOWS_DESKTOP
  std::call_once(flag, LogProcessPriorityClass);

  std::string_view taskName{ThreadTaskToNativeTask(task)};

  using KODI::PLATFORM::WINDOWS::ToW;

  m_hTask = AvSetMmThreadCharacteristicsW(ToW(taskName).c_str(), &m_taskIndex);
  if (m_hTask == 0)
  {
    CLog::LogF(LOGERROR, "unable to register thread with the multimedia scheduler ({})",
               GetLastError());
    return false;
  }

  CLog::Log(LOGDEBUG, "[threads] name: '{}' task: {}", m_name, taskName);
#endif
  return true;
}

bool CThreadImplWin::RevertTask()
{
  bool ret{true};
#ifdef TARGET_WINDOWS_DESKTOP
  std::call_once(flag, LogProcessPriorityClass);

  if (m_hTask != 0)
  {
    if (AvRevertMmThreadCharacteristics(m_hTask) == 0)
    {
Repository: xbmc/xbmc
File: xbmc/rendering/dx/RenderSystemDX.cpp (C++)

Code before:
                    , MathUtils::round_int(rect.y1)
                    , MathUtils::round_int(rect.x2)
                    , MathUtils::round_int(rect.y2));

  m_pContext->RSSetScissorRects(1, &scissor);
  m_pContext->RSSetState(m_RSScissorEnable.Get());
  m_ScissorsEnabled = true;
}

void CRenderSystemDX::ResetScissors()
{
  if (!m_bRenderCreated)
    return;

  auto m_pContext = m_deviceResources->GetD3DContext();
  auto outputSize = m_deviceResources->GetOutputSize();

  m_scissor.SetRect(0.0f, 0.0f,
    static_cast<float>(outputSize.Width),
    static_cast<float>(outputSize.Height));

  m_pContext->RSSetState(m_RSScissorDisable.Get());
  m_ScissorsEnabled = false;
}

ComPtr<ID3D11DepthStencilState> CRenderSystemDX::GetDepthStencilState()
{
  switch (m_depthCulling)
  {
    case DEPTH_CULLING::BACK_TO_FRONT:
      return m_depthStencilStateRO;
    case DEPTH_CULLING::FRONT_TO_BACK:
      return m_depthStencilStateRW;
    default:
      return m_depthStencilState;
  }
}

void CRenderSystemDX::SetDepthCulling(DEPTH_CULLING culling)
{
  if (!m_bRenderCreated)
    return;

  m_depthCulling = culling;
  m_deviceResources->GetD3DContext()->OMSetDepthStencilState(GetDepthStencilState().Get(), 0);
}

void CRenderSystemDX::OnDXDeviceLost()
{
  CRenderSystemDX::DestroyRenderSystem();
}

Review comment (suggestion):
```suggestion
ID3D11DepthStencilState* CRenderSystemDX::GetDepthStencilState()
```

Code after:
                    , MathUtils::round_int(rect.y1)
                    , MathUtils::round_int(rect.x2)
                    , MathUtils::round_int(rect.y2));

  m_pContext->RSSetScissorRects(1, &scissor);
  m_pContext->RSSetState(m_RSScissorEnable.Get());
  m_ScissorsEnabled = true;
}

void CRenderSystemDX::ResetScissors()
{
  if (!m_bRenderCreated)
    return;

  auto m_pContext = m_deviceResources->GetD3DContext();
  auto outputSize = m_deviceResources->GetOutputSize();

  m_scissor.SetRect(0.0f, 0.0f,
    static_cast<float>(outputSize.Width),
    static_cast<float>(outputSize.Height));

  m_pContext->RSSetState(m_RSScissorDisable.Get());
  m_ScissorsEnabled = false;
}

ID3D11DepthStencilState* CRenderSystemDX::GetDepthStencilState()
{
  switch (m_depthCulling)
  {
    case DEPTH_CULLING::BACK_TO_FRONT:
      return m_depthStencilStateRO.Get();
    case DEPTH_CULLING::FRONT_TO_BACK:
      return m_depthStencilStateRW.Get();
    default:
      return m_depthStencilState.Get();
  }
}

void CRenderSystemDX::SetDepthCulling(DEPTH_CULLING culling)
{
  if (!m_bRenderCreated)
    return;

  m_depthCulling = culling;
  m_deviceResources->GetD3DContext()->OMSetDepthStencilState(GetDepthStencilState(), 0);
}

void CRenderSystemDX::OnDXDeviceLost()
{
  CRenderSystemDX::DestroyRenderSystem();
}
Repository: xbmc/xbmc
File: xbmc/rendering/dx/RenderSystemDX.cpp (C++)

Code before:
  m_pContext->RSSetState(m_RSScissorEnable.Get());
  m_ScissorsEnabled = true;
}

void CRenderSystemDX::ResetScissors()
{
  if (!m_bRenderCreated)
    return;

  auto m_pContext = m_deviceResources->GetD3DContext();
  auto outputSize = m_deviceResources->GetOutputSize();

  m_scissor.SetRect(0.0f, 0.0f,
    static_cast<float>(outputSize.Width),
    static_cast<float>(outputSize.Height));

  m_pContext->RSSetState(m_RSScissorDisable.Get());
  m_ScissorsEnabled = false;
}

ComPtr<ID3D11DepthStencilState> CRenderSystemDX::GetDepthStencilState()
{
  switch (m_depthCulling)
  {
    case DEPTH_CULLING::BACK_TO_FRONT:
      return m_depthStencilStateRO;
    case DEPTH_CULLING::FRONT_TO_BACK:
      return m_depthStencilStateRW;
    default:
      return m_depthStencilState;
  }
}

void CRenderSystemDX::SetDepthCulling(DEPTH_CULLING culling)
{
  if (!m_bRenderCreated)
    return;

  m_depthCulling = culling;
  m_deviceResources->GetD3DContext()->OMSetDepthStencilState(GetDepthStencilState().Get(), 0);
}

void CRenderSystemDX::OnDXDeviceLost()
{
  CRenderSystemDX::DestroyRenderSystem();
}

void CRenderSystemDX::OnDXDeviceRestored()
{
  CRenderSystemDX::InitRenderSystem();
}

Review comment (suggestion):
```suggestion
      return m_depthStencilStateRO.Get();
```

This and others.
Also remove .Get() from callers.

Code after:
  m_pContext->RSSetState(m_RSScissorEnable.Get());
  m_ScissorsEnabled = true;
}

void CRenderSystemDX::ResetScissors()
{
  if (!m_bRenderCreated)
    return;

  auto m_pContext = m_deviceResources->GetD3DContext();
  auto outputSize = m_deviceResources->GetOutputSize();

  m_scissor.SetRect(0.0f, 0.0f,
    static_cast<float>(outputSize.Width),
    static_cast<float>(outputSize.Height));

  m_pContext->RSSetState(m_RSScissorDisable.Get());
  m_ScissorsEnabled = false;
}

ID3D11DepthStencilState* CRenderSystemDX::GetDepthStencilState()
{
  switch (m_depthCulling)
  {
    case DEPTH_CULLING::BACK_TO_FRONT:
      return m_depthStencilStateRO.Get();
    case DEPTH_CULLING::FRONT_TO_BACK:
      return m_depthStencilStateRW.Get();
    default:
      return m_depthStencilState.Get();
  }
}

void CRenderSystemDX::SetDepthCulling(DEPTH_CULLING culling)
{
  if (!m_bRenderCreated)
    return;

  m_depthCulling = culling;
  m_deviceResources->GetD3DContext()->OMSetDepthStencilState(GetDepthStencilState(), 0);
}

void CRenderSystemDX::OnDXDeviceLost()
{
  CRenderSystemDX::DestroyRenderSystem();
}

void CRenderSystemDX::OnDXDeviceRestored()
{
  CRenderSystemDX::InitRenderSystem();
}
Repository: xbmc/xbmc
File: xbmc/rendering/RenderSystem.h (C/C++)

Code before:

#pragma once

#include "RenderSystemTypes.h"
#include "threads/CriticalSection.h"
#include "utils/ColorUtils.h"
#include "utils/Geometry.h"

#include <memory>
#include <optional>
#include <string>

/*
 *   CRenderSystemBase interface allows us to create the rendering engine we use.
 *   We currently have two engines: OpenGL and DirectX
 *   This interface is very basic since a lot of the actual details will go in to the derived classes
 */

enum class DEPTH_CULLING
{
  OFF,
  BACK_TO_FRONT,
  FRONT_TO_BACK,
};

enum class CLEAR_FUNCTION
{
  FIXED_FUNCTION,
  GEOMETRY,
};

class CGUIImage;
class CGUITextLayout;

class CRenderSystemBase
{
public:
  CRenderSystemBase();
  virtual ~CRenderSystemBase();

  virtual bool InitRenderSystem() = 0;
  virtual bool DestroyRenderSystem() = 0;
  virtual bool ResetRenderSystem(int width, int height) = 0;

  virtual bool BeginRender() = 0;
  virtual bool EndRender() = 0;
  virtual void PresentRender(bool rendered, bool videoLayer) = 0;
  virtual void InvalidateColorBuffer() {}
  virtual bool ClearBuffers(KODI::UTILS::COLOR::Color color) = 0;
  virtual bool IsExtSupported(const char* extension) const = 0;


Review comment (suggestion):
`ClearFunction` per the code guidelines https://github.com/xbmc/xbmc/blob/master/docs/CODE_GUIDELINES.md#83-enums

Code after:

#pragma once

#include "RenderSystemTypes.h"
#include "threads/CriticalSection.h"
#include "utils/ColorUtils.h"
#include "utils/Geometry.h"

#include <memory>
#include <optional>
#include <string>

/*
 *   CRenderSystemBase interface allows us to create the rendering engine we use.
 *   We currently have two engines: OpenGL and DirectX
 *   This interface is very basic since a lot of the actual details will go in to the derived classes
 */

enum class DepthCulling
{
  OFF,
  BACK_TO_FRONT,
  FRONT_TO_BACK,
};

enum class ClearFunction
{
  FIXED_FUNCTION,
  GEOMETRY,
};

class CGUIImage;
class CGUITextLayout;

class CRenderSystemBase
{
public:
  CRenderSystemBase();
  virtual ~CRenderSystemBase();

  virtual bool InitRenderSystem() = 0;
  virtual bool DestroyRenderSystem() = 0;
  virtual bool ResetRenderSystem(int width, int height) = 0;

  virtual bool BeginRender() = 0;
  virtual bool EndRender() = 0;
  virtual void PresentRender(bool rendered, bool videoLayer) = 0;
  virtual void InvalidateColorBuffer() {}
  virtual bool ClearBuffers(KODI::UTILS::COLOR::Color color) = 0;
  virtual bool IsExtSupported(const char* extension) const = 0;
Repository: xbmc/xbmc
File: xbmc/platform/win32/CharsetConverter.cpp (C++)

Code before:
 *  SPDX-License-Identifier: GPL-2.0-or-later
 *  See LICENSES/README.md for more information.
 */

#include "CharsetConverter.h"

#include <cassert>

namespace KODI
{
namespace PLATFORM
{
namespace WINDOWS
{
std::string FromW(const wchar_t* str, size_t length)
{
  if (length == 0)
    return std::string();

  int result1 =
      WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, str, length, nullptr, 0, nullptr, nullptr);
  if (result1 == 0)
    return std::string();

  std::string newStr(result1, '\0');
  int result2 = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, str, length, newStr.data(),
                                    result1, nullptr, nullptr);
  assert(result1 == result2);

  if (result2 == 0 || result1 != result2)
    return std::string();

  return newStr;
}

std::string FromW(std::wstring_view str)
{
  return FromW(str.data(), str.length());
}

std::wstring ToW(const char* str, size_t length)
{
  if (length == 0)
    return std::wstring();

  int result1 = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, str, length, nullptr, 0);
  if (result1 == 0)
    return std::wstring();

  std::wstring newStr(result1, '\0');
  int result2 =

Review comment (suggestion):
@neo1973 if you have a chance, if I understood correctly this is legit since C++17?
It lets the Win API fill the string's buffer directly, avoiding a copy of the data later.

Code after:
 *  SPDX-License-Identifier: GPL-2.0-or-later
 *  See LICENSES/README.md for more information.
 */

#include "CharsetConverter.h"

#include <cassert>
#include <limits>

#include <Windows.h>

namespace KODI
{
namespace PLATFORM
{
namespace WINDOWS
{
std::string FromW(const wchar_t* str, size_t length)
{
  std::string newStr;

  if (length == 0 || length > std::numeric_limits<int>::max())
    return newStr;

  const int result1 =
      WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, str, length, nullptr, 0, nullptr, nullptr);
  if (result1 == 0)
    return newStr;

  newStr.resize(result1, '\0');
  const int result2 = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, str, length, newStr.data(),
                                          result1, nullptr, nullptr);
  assert(result1 == result2);

  if (result1 != result2)
  {
    if (result2 < result1) // less data written than expected is recoverable though still a problem
      newStr.resize(result2, '\0');
    else
      newStr.clear();
  }

  return newStr;
}

std::string FromW(std::wstring_view str)
{
  return FromW(str.data(), str.length());
}

std::wstring ToW(const char* str, size_t length)