<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <!-- Build to a folder outside the source folders, making it easier to clean. -->
    <OutDir>$(MSBuildThisFileDirectory)bin\$(Configuration)\$(Platform)\</OutDir>
    <OutDir Condition="'$(Platform)'=='Win32'">$(MSBuildThisFileDirectory)bin\$(Configuration)\x86\</OutDir>

    <!-- C# Projects require the legagy OutputPath variable. -->
    <OutputPath>$(OutDir)</OutputPath>

    <!-- C++ temp files can be redirected. -->
    <!-- C# project files can also be redirected, but this causes rebuilds inside VS2015. -->
    <IntDir>$(MSBuildThisFileDirectory)intermediate\$(MSBuildProjectName)\$(Platform)\$(Configuration)\</IntDir>

    <!-- The C runtime is provided by the OS on the Windows platform (Universal C Runtime (CRT)),
         it is necesarry to explicitly define which version to use.
         At the momement there is no way to specify to use just the latest version. -->
    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>

    <!-- Use the latest released C# language version -->
    <LangVersion>latest</LangVersion>

    <!-- Default character set is Unicode (UTF16), defines _UNICODE and UNICODE. -->
    <CharacterSet>Unicode</CharacterSet>

    <!-- Define treat warnings as errors for C# projects -->
    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>

    <CodeAnalysisRuleSet>$(MSBuildThisFileDirectory)default.ruleset</CodeAnalysisRuleSet>
  </PropertyGroup>
  <ItemDefinitionGroup>
    <ClCompile>
      <!-- To ensure high quality C++ code use Warning level All and treat warnings as errors to ensure warnings are fixed promptly. -->
      <WarningLevel>EnableAllWarnings</WarningLevel>
      <TreatWarningAsError>true</TreatWarningAsError>

      <!--
        __cplusplus = Use the correct value for the __cplusplus macro
        throwingNew = Communicate with the compiler that only the throwing variant of operator new is used.
        Disable level All warnings that are not useful:
        C4061 = enumerator 'identifier' in switch of enum 'enumeration' is not explicitly handled by a case label [Handled by default case]
        C4191 = operator/operation' : unsafe conversion from 'type of expression' to 'type required'
        C4263 = function' : member function does not override any base class virtual member function
        C4264 = virtual_function' : no override available for virtual member function from base 'class'; function is hidden
        C4266 = function' : no override available for virtual member function from base 'type'; function is hidden
        C4365 = action' : conversion from 'type_1' to 'type_2', signed/unsigned mismatch
        C4464 = A #include directive has a path that includes a '..' parent directory specifier. [Just informational]
        C4514 = function' : unreferenced inline function has been removed [Just informational]
        C4571 = Informational: catch(...) semantics changed since Visual C++ 7.1; structured exceptions (SEH) are no longer caught [Just informational]
        C4623 = derived class`' : default constructor was implicitly defined as deleted because a base class default constructor is inaccessible or deleted [Just informational]
        C4625 = derived class' : copy constructor was implicitly defined as deleted because a base class copy constructor is inaccessible or deleted [Just informational]
        C4626 = derived class' : assignment operator was implicitly defined as deleted because a base class assignment operator is inaccessible or deleted [Just informational]
        C4668 = symbol' is not defined as a preprocessor macro, replacing with '0' for 'directives' [problem in std C runtime headers when compiling as C]
        C4710 = function '' function not inlined [Just informational]
        C4711 = function '' selected for automatic inline expansion [Just informational]
        C4738 = storing 32-bit float result in memory, possible loss of performance [Just informational]
        C4820 = bytes' bytes padding added after construct 'member_name' [Just informational]
        C5026 = 'type': move constructor was implicitly defined as deleted [Just informational]
        C5027 = 'type': move assignment operator was implicitly defined as deleted [Just informational]
        C5045 = Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified [Just informational]
      -->
      <AdditionalOptions>
        /Zc:__cplusplus /Zc:throwingNew
        /wd4061 /wd4191 /wd4263 /wd4264 /wd4266 /wd4365 /wd4464 /wd4514 /wd4571 /wd4623 /wd4625 /wd4626 /wd4668
        /wd4710 /wd4711 /wd4738 /wd4820 /wd5026 /wd5027 /wd5045
      </AdditionalOptions>

      <!-- Use all cores to speed up the compilation (MS recommended best practice). -->
      <MultiProcessorCompilation>true</MultiProcessorCompilation>

      <!-- Explicit define that all projects are compiled according the latest offical C++ standard -->
      <LanguageStandard>stdcpp14</LanguageStandard>

      <!-- Explicit disable non conforming MSVC compiler options that are not compatible with the C++ standard -->
      <ConformanceMode>true</ConformanceMode>

      <AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)include</AdditionalIncludeDirectories>

      <!-- Use by default precompiled headers with the modern name pch.h -->
      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>

      <!-- For checked builds, enable the MS static analyzer build into the compiler. -->
      <EnablePREfast Condition="'$(Configuration)'=='Checked'">true</EnablePREfast>
    </ClCompile>
  </ItemDefinitionGroup>

  <PropertyGroup Condition="'$(Configuration)'=='Debug'">
    <UseDebugLibraries>true</UseDebugLibraries>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)'=='Checked'">
    <LinkIncremental>true</LinkIncremental>
    <UseDebugLibraries>true</UseDebugLibraries>
  </PropertyGroup>
</Project>