Merge pull request #6273 from leoetlino/c++17

Enable C++17
This commit is contained in:
Léo Lam 2019-05-05 10:24:18 +02:00 committed by GitHub
commit 5d52b6ff09
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
43 changed files with 118 additions and 3629 deletions

View File

@ -1,7 +1,7 @@
########################################
# General setup
#
cmake_minimum_required(VERSION 3.5.0)
cmake_minimum_required(VERSION 3.10)
set(CMAKE_OSX_ARCHITECTURES "x86_64")
# Minimum OS X version.
# This is inserted into the Info.plist as well.
@ -203,8 +203,8 @@ endif()
# Enforce minimum GCC version
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.0)
message(FATAL_ERROR "Dolphin requires at least GCC 6.0 (found ${CMAKE_CXX_COMPILER_VERSION})")
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0)
message(FATAL_ERROR "Dolphin requires at least GCC 7.0 (found ${CMAKE_CXX_COMPILER_VERSION})")
endif()
if(CMAKE_GENERATOR MATCHES "Ninja")

View File

@ -60,6 +60,7 @@ android {
externalNativeBuild {
cmake {
path "../../../CMakeLists.txt"
version "3.10.2"
}
}

View File

@ -9,26 +9,9 @@ if(CMAKE_SYSTEM_NAME MATCHES "Windows")
add_definitions(-D_CRT_SECURE_NO_DEPRECATE)
endif()
if(CMAKE_C_COMPILER_ID MATCHES "MSVC")
# enable the latest C++ standard feature set,
# and also disable MSVC specific extensions
# to be even more standards compliant.
check_and_add_flag(CPPLATEST /std:c++latest)
check_and_add_flag(STANDARD_COMPLIANCE /permissive-)
else()
# Enable C++17, but fall back to C++14 if it isn't available.
# CMAKE_CXX_STANDARD cannot be used here because we require C++14 or newer, not any standard.
check_and_add_flag(CXX17 -std=c++17)
if(NOT FLAG_CXX_CXX17)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
endif()
# These compat headers must not be in the include path when building with MSVC,
# because it currently does not support __has_include_next / #include_next.
include_directories(SYSTEM Core/Common/Compat)
endif()
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
# These aren't actually needed for C11/C++11
# but some dependencies require them (LLVM, libav).

View File

@ -4,13 +4,13 @@
#include "AudioCommon/Mixer.h"
#include <algorithm>
#include <cmath>
#include <cstring>
#include "Common/ChunkFile.h"
#include "Common/CommonTypes.h"
#include "Common/Logging/Log.h"
#include "Common/MathUtil.h"
#include "Common/Swap.h"
#include "Core/ConfigManager.h"
@ -86,14 +86,14 @@ unsigned int Mixer::MixerFifo::Mix(short* samples, unsigned int numSamples,
int sampleL = ((l1 << 16) + (l2 - l1) * (u16)m_frac) >> 16;
sampleL = (sampleL * lvolume) >> 8;
sampleL += samples[currentSample + 1];
samples[currentSample + 1] = MathUtil::Clamp(sampleL, -32767, 32767);
samples[currentSample + 1] = std::clamp(sampleL, -32767, 32767);
s16 r1 = Common::swap16(m_buffer[(indexR + 1) & INDEX_MASK]); // current
s16 r2 = Common::swap16(m_buffer[(indexR2 + 1) & INDEX_MASK]); // next
int sampleR = ((r1 << 16) + (r2 - r1) * (u16)m_frac) >> 16;
sampleR = (sampleR * rvolume) >> 8;
sampleR += samples[currentSample];
samples[currentSample] = MathUtil::Clamp(sampleR, -32767, 32767);
samples[currentSample] = std::clamp(sampleR, -32767, 32767);
m_frac += ratio;
indexR += 2 * (u16)(m_frac >> 16);
@ -111,8 +111,8 @@ unsigned int Mixer::MixerFifo::Mix(short* samples, unsigned int numSamples,
s[1] = (s[1] * lvolume) >> 8;
for (; currentSample < numSamples * 2; currentSample += 2)
{
int sampleR = MathUtil::Clamp(s[0] + samples[currentSample + 0], -32767, 32767);
int sampleL = MathUtil::Clamp(s[1] + samples[currentSample + 1], -32767, 32767);
int sampleR = std::clamp(s[0] + samples[currentSample + 0], -32767, 32767);
int sampleL = std::clamp(s[1] + samples[currentSample + 1], -32767, 32767);
samples[currentSample + 0] = sampleR;
samples[currentSample + 1] = sampleL;

View File

@ -1,45 +0,0 @@
// Copyright 2017 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#pragma once
// MPark.Variant
//
// Copyright Michael Park, 2015-2017
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
#include <cstddef>
namespace mpark
{
struct in_place_t
{
explicit in_place_t() = default;
};
template <std::size_t I>
struct in_place_index_t
{
explicit in_place_index_t() = default;
};
template <typename T>
struct in_place_type_t
{
explicit in_place_type_t() = default;
};
#ifdef MPARK_VARIABLE_TEMPLATES
constexpr in_place_t in_place{};
template <std::size_t I>
constexpr in_place_index_t<I> in_place_index{};
template <typename T>
constexpr in_place_type_t<T> in_place_type{};
#endif
} // namespace mpark

View File

@ -1,907 +0,0 @@
// Copyright 2017 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#pragma once
#if __cplusplus >= 201703L && __has_include_next(<optional>)
#include_next <optional>
#else
/* Copyright 2017 The TensorFlow Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
#include <cassert>
#include <functional>
#include <initializer_list>
#include <type_traits>
#include <utility>
#ifndef __has_feature
#define __has_feature(x) 0
#endif
#if __has_feature(cxx_exceptions) || defined(__cpp_exceptions)
#define GTL_HAS_EXCEPTIONS
#endif
namespace gtl {
// A value of type gtl::optional<T> holds either a value of T or an
// "empty" value. When it holds a value of T, it stores it as a direct
// subobject, so sizeof(optional<T>) is approximately sizeof(T)+1. The interface
// is based on the upcoming std::optional<T>, and gtl::optional<T> is
// designed to be cheaply drop-in replaceable by std::optional<T>, once it is
// rolled out.
//
// This implementation is based on the specification in the latest draft as of
// 2017-01-05, section 20.6.
//
// Differences between gtl::optional<T> and std::optional<T> include:
// - constexpr not used for nonconst member functions.
// (dependency on some differences between C++11 and C++14.)
// - nullopt and in_place are not constexpr. We need the inline variable
// support in C++17 for external linkage.
// - optional::swap() and swap() relies on std::is_(nothrow_)swappable
// which is introduced in C++17. So we assume is_swappable is always true
// and is_nothrow_swappable is same as std::is_trivial.
// - make_optional cannot be constexpr due to absence of guaranteed copy
// elision.
//
// Synopsis:
//
// #include "tensorflow/core/lib/gtl/optional.h"
//
// tensorflow::gtl::optional<string> f() {
// string result;
// if (...) {
// ...
// result = ...;
// return result;
// } else {
// ...
// return tensorflow::gtl::nullopt;
// }
// }
//
// int main() {
// tensorflow::gtl::optional<string> optstr = f();
// if (optstr) {
// // non-empty
// print(optstr.value());
// } else {
// // empty
// error();
// }
// }
template <typename T>
class optional;
// The tag constant `in_place` is used as the first parameter of an optional<T>
// constructor to indicate that the remaining arguments should be forwarded
// to the underlying T constructor.
struct in_place_t {};
extern const in_place_t in_place;
// The tag constant `nullopt` is used to indicate an empty optional<T> in
// certain functions, such as construction or assignment.
struct nullopt_t {
struct init_t {};
static init_t init;
// It must not be default-constructible to avoid ambiguity for opt = {}.
// Note the non-const reference, it is to eliminate ambiguity for code like:
// struct S { int value; };
//
// void Test() {
// optional<S> opt;
// opt = {{}};
// }
explicit constexpr nullopt_t(init_t& /*unused*/) {} // NOLINT
};
extern const nullopt_t nullopt;
class bad_optional_access : public std::exception
{
public:
virtual const char* what() const noexcept { return "bad_optional_access"; }
};
[[noreturn]] inline void throw_bad_optional_access()
{
#ifdef GTL_HAS_EXCEPTIONS
throw bad_optional_access{};
#else
std::terminate();
#endif
}
namespace internal_optional {
// define forward locally because std::forward is not constexpr until C++14
template <typename T>
constexpr T&& forward(typename std::remove_reference<T>::type&
t) noexcept { // NOLINT(runtime/references)
return static_cast<T&&>(t);
}
struct empty_struct {};
// This class stores the data in optional<T>.
// It is specialized based on whether T is trivially destructible.
// This is the specialization for non trivially destructible type.
template <typename T, bool = std::is_trivially_destructible<T>::value>
class optional_data_dtor_base {
protected:
// Whether there is data or not.
bool engaged_;
// data storage
union {
empty_struct dummy_;
T data_;
};
void destruct() noexcept {
if (engaged_) {
data_.~T();
engaged_ = false;
}
}
// dummy_ must be initialized for constexpr constructor
constexpr optional_data_dtor_base() noexcept : engaged_(false), dummy_{} {}
template <typename... Args>
constexpr explicit optional_data_dtor_base(in_place_t, Args&&... args)
: engaged_(true), data_(internal_optional::forward<Args>(args)...) {}
~optional_data_dtor_base() { destruct(); }
};
// Specialization for trivially destructible type.
template <typename T>
class optional_data_dtor_base<T, true> {
protected:
// Whether there is data or not.
bool engaged_;
// data storage
union {
empty_struct dummy_;
T data_;
};
void destruct() noexcept { engaged_ = false; }
// dummy_ must be initialized for constexpr constructor
constexpr optional_data_dtor_base() noexcept : engaged_(false), dummy_{} {}
template <typename... Args>
constexpr explicit optional_data_dtor_base(in_place_t, Args&&... args)
: engaged_(true), data_(internal_optional::forward<Args>(args)...) {}
~optional_data_dtor_base() = default;
};
template <typename T>
class optional_data : public optional_data_dtor_base<T> {
protected:
using base = optional_data_dtor_base<T>;
using base::base;
T* pointer() { return &this->data_; }
constexpr const T* pointer() const { return &this->data_; }
template <typename... Args>
void construct(Args&&... args) {
new (pointer()) T(std::forward<Args>(args)...);
this->engaged_ = true;
}
template <typename U>
void assign(U&& u) {
if (this->engaged_) {
this->data_ = std::forward<U>(u);
} else {
construct(std::forward<U>(u));
}
}
optional_data() = default;
optional_data(const optional_data& rhs) {
if (rhs.engaged_) {
construct(rhs.data_);
}
}
optional_data(optional_data&& rhs) noexcept(
std::is_nothrow_move_constructible<T>::value) {
if (rhs.engaged_) {
construct(std::move(rhs.data_));
}
}
optional_data& operator=(const optional_data& rhs) {
if (rhs.engaged_) {
assign(rhs.data_);
} else {
this->destruct();
}
return *this;
}
optional_data& operator=(optional_data&& rhs) noexcept(
std::is_nothrow_move_assignable<T>::value&&
std::is_nothrow_move_constructible<T>::value) {
if (rhs.engaged_) {
assign(std::move(rhs.data_));
} else {
this->destruct();
}
return *this;
}
};
// ordered by level of restriction, from low to high.
// copyable implies movable.
enum class copy_traits { copyable = 0, movable = 1, non_movable = 2 };
// base class for enabling/disabling copy/move constructor.
template <copy_traits>
class optional_ctor_base;
template <>
class optional_ctor_base<copy_traits::copyable> {
public:
constexpr optional_ctor_base() = default;
optional_ctor_base(const optional_ctor_base&) = default;
optional_ctor_base(optional_ctor_base&&) = default;
optional_ctor_base& operator=(const optional_ctor_base&) = default;
optional_ctor_base& operator=(optional_ctor_base&&) = default;
};
template <>
class optional_ctor_base<copy_traits::movable> {
public:
constexpr optional_ctor_base() = default;
optional_ctor_base(const optional_ctor_base&) = delete;
optional_ctor_base(optional_ctor_base&&) = default;
optional_ctor_base& operator=(const optional_ctor_base&) = default;
optional_ctor_base& operator=(optional_ctor_base&&) = default;
};
template <>
class optional_ctor_base<copy_traits::non_movable> {
public:
constexpr optional_ctor_base() = default;
optional_ctor_base(const optional_ctor_base&) = delete;
optional_ctor_base(optional_ctor_base&&) = delete;
optional_ctor_base& operator=(const optional_ctor_base&) = default;
optional_ctor_base& operator=(optional_ctor_base&&) = default;
};
// base class for enabling/disabling copy/move assignment.
template <copy_traits>
class optional_assign_base;
template <>
class optional_assign_base<copy_traits::copyable> {
public:
constexpr optional_assign_base() = default;
optional_assign_base(const optional_assign_base&) = default;
optional_assign_base(optional_assign_base&&) = default;
optional_assign_base& operator=(const optional_assign_base&) = default;
optional_assign_base& operator=(optional_assign_base&&) = default;
};
template <>
class optional_assign_base<copy_traits::movable> {
public:
constexpr optional_assign_base() = default;
optional_assign_base(const optional_assign_base&) = default;
optional_assign_base(optional_assign_base&&) = default;
optional_assign_base& operator=(const optional_assign_base&) = delete;
optional_assign_base& operator=(optional_assign_base&&) = default;
};
template <>
class optional_assign_base<copy_traits::non_movable> {
public:
constexpr optional_assign_base() = default;
optional_assign_base(const optional_assign_base&) = default;
optional_assign_base(optional_assign_base&&) = default;
optional_assign_base& operator=(const optional_assign_base&) = delete;
optional_assign_base& operator=(optional_assign_base&&) = delete;
};
template <typename T>
constexpr copy_traits get_ctor_copy_traits() {
return std::is_copy_constructible<T>::value
? copy_traits::copyable
: std::is_move_constructible<T>::value ? copy_traits::movable
: copy_traits::non_movable;
}
template <typename T>
constexpr copy_traits get_assign_copy_traits() {
return std::is_copy_assignable<T>::value &&
std::is_copy_constructible<T>::value
? copy_traits::copyable
: std::is_move_assignable<T>::value &&
std::is_move_constructible<T>::value
? copy_traits::movable
: copy_traits::non_movable;
}
// Whether T is constructible or convertible from optional<U>.
template <typename T, typename U>
struct is_constructible_convertible_from_optional
: std::integral_constant<
bool, std::is_constructible<T, optional<U>&>::value ||
std::is_constructible<T, optional<U>&&>::value ||
std::is_constructible<T, const optional<U>&>::value ||
std::is_constructible<T, const optional<U>&&>::value ||
std::is_convertible<optional<U>&, T>::value ||
std::is_convertible<optional<U>&&, T>::value ||
std::is_convertible<const optional<U>&, T>::value ||
std::is_convertible<const optional<U>&&, T>::value> {};
// Whether T is constructible or convertible or assignable from optional<U>.
template <typename T, typename U>
struct is_constructible_convertible_assignable_from_optional
: std::integral_constant<
bool, is_constructible_convertible_from_optional<T, U>::value ||
std::is_assignable<T&, optional<U>&>::value ||
std::is_assignable<T&, optional<U>&&>::value ||
std::is_assignable<T&, const optional<U>&>::value ||
std::is_assignable<T&, const optional<U>&&>::value> {};
} // namespace internal_optional
template <typename T>
class optional : private internal_optional::optional_data<T>,
private internal_optional::optional_ctor_base<
internal_optional::get_ctor_copy_traits<T>()>,
private internal_optional::optional_assign_base<
internal_optional::get_assign_copy_traits<T>()> {
using data_base = internal_optional::optional_data<T>;
public:
typedef T value_type;
// [optional.ctor], constructors
// A default constructed optional holds the empty value, NOT a default
// constructed T.
constexpr optional() noexcept {}
// An optional initialized with `nullopt` holds the empty value.
constexpr optional(nullopt_t) noexcept {} // NOLINT(runtime/explicit)
// Copy constructor, standard semantics.
optional(const optional& src) = default;
// Move constructor, standard semantics.
optional(optional&& src) = default;
// optional<T>(in_place, arg1, arg2, arg3) constructs a non-empty optional
// with an in-place constructed value of T(arg1,arg2,arg3).
// TODO(b/34201852): Add std::is_constructible<T, Args&&...> SFINAE.
template <typename... Args>
constexpr explicit optional(in_place_t, Args&&... args)
: data_base(in_place_t(), internal_optional::forward<Args>(args)...) {}
// optional<T>(in_place, {arg1, arg2, arg3}) constructs a non-empty optional
// with an in-place list-initialized value of T({arg1, arg2, arg3}).
template <typename U, typename... Args,
typename = typename std::enable_if<std::is_constructible<
T, std::initializer_list<U>&, Args&&...>::value>::type>
constexpr explicit optional(in_place_t, std::initializer_list<U> il,
Args&&... args)
: data_base(in_place_t(), il, internal_optional::forward<Args>(args)...) {
}
template <
typename U = T,
typename std::enable_if<
std::is_constructible<T, U&&>::value &&
!std::is_same<in_place_t, typename std::decay<U>::type>::value &&
!std::is_same<optional<T>, typename std::decay<U>::type>::value &&
std::is_convertible<U&&, T>::value,
bool>::type = false>
constexpr optional(U&& v) // NOLINT
: data_base(in_place_t(), internal_optional::forward<U>(v)) {}
template <
typename U = T,
typename std::enable_if<
std::is_constructible<T, U&&>::value &&
!std::is_same<in_place_t, typename std::decay<U>::type>::value &&
!std::is_same<optional<T>, typename std::decay<U>::type>::value &&
!std::is_convertible<U&&, T>::value,
bool>::type = false>
explicit constexpr optional(U&& v)
: data_base(in_place_t(), internal_optional::forward<U>(v)) {}
// Converting copy constructor (implicit)
template <
typename U,
typename std::enable_if<
std::is_constructible<T, const U&>::value &&
!internal_optional::is_constructible_convertible_from_optional<
T, U>::value &&
std::is_convertible<const U&, T>::value,
bool>::type = false>
optional(const optional<U>& rhs) { // NOLINT
if (rhs) {
this->construct(*rhs);
}
}
// Converting copy constructor (explicit)
template <
typename U,
typename std::enable_if<
std::is_constructible<T, const U&>::value &&
!internal_optional::is_constructible_convertible_from_optional<
T, U>::value &&
!std::is_convertible<const U&, T>::value,
bool>::type = false>
explicit optional(const optional<U>& rhs) {
if (rhs) {
this->construct(*rhs);
}
}
// Converting move constructor (implicit)
template <
typename U,
typename std::enable_if<
std::is_constructible<T, U&&>::value &&
!internal_optional::is_constructible_convertible_from_optional<
T, U>::value &&
std::is_convertible<U&&, T>::value,
bool>::type = false>
optional(optional<U>&& rhs) { // NOLINT
if (rhs) {
this->construct(std::move(*rhs));
}
}
// Converting move constructor (explicit)
template <
typename U,
typename std::enable_if<
std::is_constructible<T, U&&>::value &&
!internal_optional::is_constructible_convertible_from_optional<
T, U>::value &&
!std::is_convertible<U&&, T>::value,
bool>::type = false>
explicit optional(optional<U>&& rhs) {
if (rhs) {
this->construct(std::move(*rhs));
}
}
// [optional.dtor], destructor, trivial if T is trivially destructible.
~optional() = default;
// [optional.assign], assignment
// Assignment from nullopt: opt = nullopt
optional& operator=(nullopt_t) noexcept {
this->destruct();
return *this;
}
// Copy assigment, standard semantics.
optional& operator=(const optional& src) = default;
// Move assignment, standard semantics.
optional& operator=(optional&& src) = default;
// Value assignment
template <
typename U = T,
typename = typename std::enable_if<
!std::is_same<optional<T>, typename std::decay<U>::type>::value &&
(!std::is_scalar<T>::value ||
!std::is_same<T, typename std::decay<U>::type>::value) &&
std::is_constructible<T, U>::value &&
std::is_assignable<T&, U>::value>::type>
optional& operator=(U&& v) {
this->assign(std::forward<U>(v));
return *this;
}
template <typename U,
typename = typename std::enable_if<
std::is_constructible<T, const U&>::value &&
std::is_assignable<T&, const U&>::value &&
!internal_optional::
is_constructible_convertible_assignable_from_optional<
T, U>::value>::type>
optional& operator=(const optional<U>& rhs) {
if (rhs) {
this->assign(*rhs);
} else {
this->destruct();
}
return *this;
}
template <typename U,
typename = typename std::enable_if<
std::is_constructible<T, U>::value &&
std::is_assignable<T&, U>::value &&
!internal_optional::
is_constructible_convertible_assignable_from_optional<
T, U>::value>::type>
optional& operator=(optional<U>&& rhs) {
if (rhs) {
this->assign(std::move(*rhs));
} else {
this->destruct();
}
return *this;
}
// [optional.mod], modifiers
// Destroys the inner T value if one is present.
void reset() noexcept { this->destruct(); }
// Emplace reconstruction. (Re)constructs the underlying T in-place with the
// given arguments forwarded:
//
// optional<Foo> opt;
// opt.emplace(arg1,arg2,arg3); (Constructs Foo(arg1,arg2,arg3))
//
// If the optional is non-empty, and the `args` refer to subobjects of the
// current object, then behavior is undefined. This is because the current
// object will be destructed before the new object is constructed with `args`.
//
template <typename... Args,
typename = typename std::enable_if<
std::is_constructible<T, Args&&...>::value>::type>
void emplace(Args&&... args) {
this->destruct();
this->construct(std::forward<Args>(args)...);
}
// Emplace reconstruction with initializer-list. See immediately above.
template <class U, class... Args,
typename = typename std::enable_if<std::is_constructible<
T, std::initializer_list<U>&, Args&&...>::value>::type>
void emplace(std::initializer_list<U> il, Args&&... args) {
this->destruct();
this->construct(il, std::forward<Args>(args)...);
}
// [optional.swap], swap
// Swap, standard semantics.
void swap(optional& rhs) noexcept(
std::is_nothrow_move_constructible<T>::value&&
std::is_trivial<T>::value) {
if (*this) {
if (rhs) {
using std::swap;
swap(**this, *rhs);
} else {
rhs.construct(std::move(**this));
this->destruct();
}
} else {
if (rhs) {
this->construct(std::move(*rhs));
rhs.destruct();
} else {
// no effect (swap(disengaged, disengaged))
}
}
}
// [optional.observe], observers
// You may use `*opt`, and `opt->m`, to access the underlying T value and T's
// member `m`, respectively. If the optional is empty, behavior is
// undefined.
constexpr const T* operator->() const { return this->pointer(); }
T* operator->() {
assert(this->engaged_);
return this->pointer();
}
constexpr const T& operator*() const & { return reference(); }
T& operator*() & {
assert(this->engaged_);
return reference();
}
constexpr const T&& operator*() const && { return std::move(reference()); }
T&& operator*() && {
assert(this->engaged_);
return std::move(reference());
}
// In a bool context an optional<T> will return false if and only if it is
// empty.
//
// if (opt) {
// // do something with opt.value();
// } else {
// // opt is empty
// }
//
constexpr explicit operator bool() const noexcept { return this->engaged_; }
// Returns false if and only if *this is empty.
constexpr bool has_value() const noexcept { return this->engaged_; }
// Use `opt.value()` to get a reference to underlying value. The constness
// and lvalue/rvalue-ness of `opt` is preserved to the view of the T
// subobject.
const T& value() const & {
if (!*this)
throw_bad_optional_access();
return reference();
}
T& value() & {
if (!*this)
throw_bad_optional_access();
return reference();
}
T&& value() && { // NOLINT(build/c++11)
if (!*this)
throw_bad_optional_access();
return std::move(reference());
}
const T&& value() const && { // NOLINT(build/c++11)
if (!*this)
throw_bad_optional_access();
return std::move(reference());
}
// Use `opt.value_or(val)` to get either the value of T or the given default
// `val` in the empty case.
template <class U>
constexpr T value_or(U&& v) const & {
return static_cast<bool>(*this) ? **this
: static_cast<T>(std::forward<U>(v));
}
template <class U>
T value_or(U&& v) && { // NOLINT(build/c++11)
return static_cast<bool>(*this) ? std::move(**this)
: static_cast<T>(std::forward<U>(v));
}
private:
// Private accessors for internal storage viewed as reference to T.
constexpr const T& reference() const { return *this->pointer(); }
T& reference() { return *(this->pointer()); }
// T constaint checks. You can't have an optional of nullopt_t, in_place_t or
// a reference.
static_assert(
!std::is_same<nullopt_t, typename std::remove_cv<T>::type>::value,
"optional<nullopt_t> is not allowed.");
static_assert(
!std::is_same<in_place_t, typename std::remove_cv<T>::type>::value,
"optional<in_place_t> is not allowed.");
static_assert(!std::is_reference<T>::value,
"optional<reference> is not allowed.");
};
// [optional.specalg]
// Swap, standard semantics.
// This function shall not participate in overload resolution unless
// is_move_constructible_v<T> is true and is_swappable_v<T> is true.
// NOTE: we assume is_swappable is always true. There will be a compiling error
// if T is actually not Swappable.
template <typename T,
typename std::enable_if<std::is_move_constructible<T>::value,
bool>::type = false>
void swap(optional<T>& a, optional<T>& b) noexcept(noexcept(a.swap(b))) {
a.swap(b);
}
// NOTE: make_optional cannot be constexpr in C++11 because the copy/move
// constructor is not constexpr and we don't have guaranteed copy elision
// util C++17. But they are still declared constexpr for consistency with
// the standard.
// make_optional(v) creates a non-empty optional<T> where the type T is deduced
// from v. Can also be explicitly instantiated as make_optional<T>(v).
template <typename T>
constexpr optional<typename std::decay<T>::type> make_optional(T&& v) {
return optional<typename std::decay<T>::type>(std::forward<T>(v));
}
template <typename T, typename... Args>
constexpr optional<T> make_optional(Args&&... args) {
return optional<T>(in_place_t(), internal_optional::forward<Args>(args)...);
}
template <typename T, typename U, typename... Args>
constexpr optional<T> make_optional(std::initializer_list<U> il,
Args&&... args) {
return optional<T>(in_place_t(), il,
internal_optional::forward<Args>(args)...);
}
// Relational operators. Empty optionals are considered equal to each
// other and less than non-empty optionals. Supports relations between
// optional<T> and optional<T>, between optional<T> and T, and between
// optional<T> and nullopt.
// Note: We're careful to support T having non-bool relationals.
// Relational operators [optional.relops]
// The C++17 (N4606) "Returns:" statements are translated into code
// in an obvious way here, and the original text retained as function docs.
// Returns: If bool(x) != bool(y), false; otherwise if bool(x) == false, true;
// otherwise *x == *y.
template <class T>
constexpr bool operator==(const optional<T>& x, const optional<T>& y) {
return static_cast<bool>(x) != static_cast<bool>(y)
? false
: static_cast<bool>(x) == false ? true : *x == *y;
}
// Returns: If bool(x) != bool(y), true; otherwise, if bool(x) == false, false;
// otherwise *x != *y.
template <class T>
constexpr bool operator!=(const optional<T>& x, const optional<T>& y) {
return static_cast<bool>(x) != static_cast<bool>(y)
? true
: static_cast<bool>(x) == false ? false : *x != *y;
}
// Returns: If !y, false; otherwise, if !x, true; otherwise *x < *y.
template <class T>
constexpr bool operator<(const optional<T>& x, const optional<T>& y) {
return !y ? false : !x ? true : *x < *y;
}
// Returns: If !x, false; otherwise, if !y, true; otherwise *x > *y.
template <class T>
constexpr bool operator>(const optional<T>& x, const optional<T>& y) {
return !x ? false : !y ? true : *x > *y;
}
// Returns: If !x, true; otherwise, if !y, false; otherwise *x <= *y.
template <class T>
constexpr bool operator<=(const optional<T>& x, const optional<T>& y) {
return !x ? true : !y ? false : *x <= *y;
}
// Returns: If !y, true; otherwise, if !x, false; otherwise *x >= *y.
template <class T>
constexpr bool operator>=(const optional<T>& x, const optional<T>& y) {
return !y ? true : !x ? false : *x >= *y;
}
// Comparison with nullopt [optional.nullops]
// The C++17 (N4606) "Returns:" statements are used directly here.
template <class T>
constexpr bool operator==(const optional<T>& x, nullopt_t) noexcept {
return !x;
}
template <class T>
constexpr bool operator==(nullopt_t, const optional<T>& x) noexcept {
return !x;
}
template <class T>
constexpr bool operator!=(const optional<T>& x, nullopt_t) noexcept {
return static_cast<bool>(x);
}
template <class T>
constexpr bool operator!=(nullopt_t, const optional<T>& x) noexcept {
return static_cast<bool>(x);
}
template <class T>
constexpr bool operator<(const optional<T>& x, nullopt_t) noexcept {
return false;
}
template <class T>
constexpr bool operator<(nullopt_t, const optional<T>& x) noexcept {
return static_cast<bool>(x);
}
template <class T>
constexpr bool operator<=(const optional<T>& x, nullopt_t) noexcept {
return !x;
}
template <class T>
constexpr bool operator<=(nullopt_t, const optional<T>& x) noexcept {
return true;
}
template <class T>
constexpr bool operator>(const optional<T>& x, nullopt_t) noexcept {
return static_cast<bool>(x);
}
template <class T>
constexpr bool operator>(nullopt_t, const optional<T>& x) noexcept {
return false;
}
template <class T>
constexpr bool operator>=(const optional<T>& x, nullopt_t) noexcept {
return true;
}
template <class T>
constexpr bool operator>=(nullopt_t, const optional<T>& x) noexcept {
return !x;
}
// Comparison with T [optional.comp_with_t]
// The C++17 (N4606) "Equivalent to:" statements are used directly here.
template <class T>
constexpr bool operator==(const optional<T>& x, const T& v) {
return static_cast<bool>(x) ? *x == v : false;
}
template <class T>
constexpr bool operator==(const T& v, const optional<T>& x) {
return static_cast<bool>(x) ? v == *x : false;
}
template <class T>
constexpr bool operator!=(const optional<T>& x, const T& v) {
return static_cast<bool>(x) ? *x != v : true;
}
template <class T>
constexpr bool operator!=(const T& v, const optional<T>& x) {
return static_cast<bool>(x) ? v != *x : true;
}
template <class T>
constexpr bool operator<(const optional<T>& x, const T& v) {
return static_cast<bool>(x) ? *x < v : true;
}
template <class T>
constexpr bool operator<(const T& v, const optional<T>& x) {
return static_cast<bool>(x) ? v < *x : false;
}
template <class T>
constexpr bool operator<=(const optional<T>& x, const T& v) {
return static_cast<bool>(x) ? *x <= v : true;
}
template <class T>
constexpr bool operator<=(const T& v, const optional<T>& x) {
return static_cast<bool>(x) ? v <= *x : false;
}
template <class T>
constexpr bool operator>(const optional<T>& x, const T& v) {
return static_cast<bool>(x) ? *x > v : false;
}
template <class T>
constexpr bool operator>(const T& v, const optional<T>& x) {
return static_cast<bool>(x) ? v > *x : true;
}
template <class T>
constexpr bool operator>=(const optional<T>& x, const T& v) {
return static_cast<bool>(x) ? *x >= v : false;
}
template <class T>
constexpr bool operator>=(const T& v, const optional<T>& x) {
return static_cast<bool>(x) ? v >= *x : true;
}
} // namespace gtl
namespace std {
template <class T>
struct hash<::gtl::optional<T>> {
size_t operator()(const ::gtl::optional<T>& opt) const {
if (opt) {
return hash<T>()(*opt);
} else {
return static_cast<size_t>(0x297814aaad196e6dULL);
}
}
};
using ::gtl::optional;
using ::gtl::bad_optional_access;
using ::gtl::nullopt_t;
using ::gtl::nullopt;
using ::gtl::make_optional;
} // namespace std
#endif

File diff suppressed because it is too large Load Diff

View File

@ -4,15 +4,6 @@
#pragma once
// TODO: Replace this with [[maybe_unused]] directly when GCC 7 and clang 3.9
// are hard requirements.
#if defined(__GNUC__) || __clang__
// Disable "unused function" warnings for the ones manually marked as such.
#define DOLPHIN_UNUSED __attribute__((unused))
#else
#define DOLPHIN_UNUSED [[maybe_unused]]
#endif
#ifdef _WIN32
#define DOLPHIN_FORCE_INLINE __forceinline
#else

View File

@ -173,7 +173,7 @@ private:
};
// y**2 + x*y = x**3 + x + b
DOLPHIN_UNUSED static const u8 ec_b[30] = {
[[maybe_unused]] static const u8 ec_b[30] = {
0x00, 0x66, 0x64, 0x7e, 0xde, 0x6c, 0x33, 0x2c, 0x7f, 0x8c, 0x09, 0x23, 0xbb, 0x58, 0x21,
0x3b, 0x33, 0x3b, 0x20, 0xe9, 0xce, 0x42, 0x81, 0xfe, 0x11, 0x5f, 0x7d, 0x8f, 0x90, 0xad};

View File

@ -18,12 +18,6 @@ namespace MathUtil
constexpr double TAU = 6.2831853071795865;
constexpr double PI = TAU / 2;
template <class T>
constexpr T Clamp(const T val, const T& min, const T& max)
{
return std::max(min, std::min(max, val));
}
template <typename T>
constexpr auto Sign(const T& val) -> decltype((T{} < val) - (val < T{}))
{
@ -81,20 +75,20 @@ struct Rectangle
// this Clamp.
void ClampLL(T x1, T y1, T x2, T y2)
{
left = Clamp(left, x1, x2);
right = Clamp(right, x1, x2);
top = Clamp(top, y2, y1);
bottom = Clamp(bottom, y2, y1);
left = std::clamp(left, x1, x2);
right = std::clamp(right, x1, x2);
top = std::clamp(top, y2, y1);
bottom = std::clamp(bottom, y2, y1);
}
// If the rectangle is in a coordinate system with an upper-left origin,
// use this Clamp.
void ClampUL(T x1, T y1, T x2, T y2)
{
left = Clamp(left, x1, x2);
right = Clamp(right, x1, x2);
top = Clamp(top, y1, y2);
bottom = Clamp(bottom, y1, y2);
left = std::clamp(left, x1, x2);
right = std::clamp(right, x1, x2);
top = std::clamp(top, y1, y2);
bottom = std::clamp(bottom, y1, y2);
}
};

View File

@ -2,12 +2,13 @@
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include <algorithm>
#include "Core/DSP/DSPAccelerator.h"
#include "Common/ChunkFile.h"
#include "Common/CommonTypes.h"
#include "Common/Logging/Log.h"
#include "Common/MathUtil.h"
namespace DSP
{
@ -89,7 +90,7 @@ u16 Accelerator::Read(const s16* coefs)
temp -= 16;
s32 val32 = (scale * temp) + ((0x400 + coef1 * m_yn1 + coef2 * m_yn2) >> 11);
val = static_cast<s16>(MathUtil::Clamp<s32>(val32, -0x7FFF, 0x7FFF));
val = static_cast<s16>(std::clamp<s32>(val32, -0x7FFF, 0x7FFF));
step_size_bytes = 2;
m_yn2 = m_yn1;

View File

@ -2,6 +2,8 @@
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include <algorithm>
#include "Core/HW/DSPHLE/UCodes/AX.h"
#include "Common/ChunkFile.h"
@ -9,7 +11,6 @@
#include "Common/File.h"
#include "Common/FileUtil.h"
#include "Common/Logging/Log.h"
#include "Common/MathUtil.h"
#include "Common/Swap.h"
#include "Core/HW/DSP.h"
#include "Core/HW/DSPHLE/DSPHLE.h"
@ -535,8 +536,8 @@ void AXUCode::OutputSamples(u32 lr_addr, u32 surround_addr)
// Output samples clamped to 16 bits and interlaced RLRLRLRLRL...
for (u32 i = 0; i < 5 * 32; ++i)
{
int left = MathUtil::Clamp(m_samples_left[i], -32767, 32767);
int right = MathUtil::Clamp(m_samples_right[i], -32767, 32767);
int left = std::clamp(m_samples_left[i], -32767, 32767);
int right = std::clamp(m_samples_right[i], -32767, 32767);
buffer[2 * i + 0] = Common::swap16(right);
buffer[2 * i + 1] = Common::swap16(left);

View File

@ -12,11 +12,11 @@
#error AXVoice.h included without specifying version
#endif
#include <algorithm>
#include <functional>
#include <memory>
#include "Common/CommonTypes.h"
#include "Common/MathUtil.h"
#include "Core/DSP/DSPAccelerator.h"
#include "Core/HW/DSP.h"
#include "Core/HW/DSPHLE/UCodes/AX.h"
@ -413,7 +413,7 @@ void MixAdd(int* out, const s16* input, u32 count, u16* pvol, s16* dpop, bool ra
s64 sample = input[i];
sample *= volume;
sample >>= 15;
sample = MathUtil::Clamp((s32)sample, -32767, 32767); // -32768 ?
sample = std::clamp((s32)sample, -32767, 32767); // -32768 ?
out[i] += (s16)sample;
volume += volume_delta;
@ -447,8 +447,8 @@ void ProcessVoice(PB_TYPE& pb, const AXBuffers& buffers, u16 count, AXMixControl
// Apply a global volume ramp using the volume envelope parameters.
for (u32 i = 0; i < count; ++i)
{
samples[i] = MathUtil::Clamp(((s32)samples[i] * pb.vol_env.cur_volume) >> 15, -32767,
32767); // -32768 ?
samples[i] = std::clamp(((s32)samples[i] * pb.vol_env.cur_volume) >> 15, -32767,
32767); // -32768 ?
pb.vol_env.cur_volume += pb.vol_env.cur_volume_delta;
}

View File

@ -4,12 +4,13 @@
//
#define AX_WII // Used in AXVoice.
#include <algorithm>
#include "Core/HW/DSPHLE/UCodes/AXWii.h"
#include "Common/ChunkFile.h"
#include "Common/CommonTypes.h"
#include "Common/Logging/Log.h"
#include "Common/MathUtil.h"
#include "Common/Swap.h"
#include "Core/HW/DSPHLE/DSPHLE.h"
#include "Core/HW/DSPHLE/MailHandler.h"
@ -602,8 +603,8 @@ void AXWiiUCode::OutputSamples(u32 lr_addr, u32 surround_addr, u16 volume, bool
left = ((s64)left * volume_ramp[i]) >> 15;
right = ((s64)right * volume_ramp[i]) >> 15;
m_samples_left[i] = MathUtil::Clamp(left, -32767, 32767);
m_samples_right[i] = MathUtil::Clamp(right, -32767, 32767);
m_samples_left[i] = std::clamp(left, -32767, 32767);
m_samples_right[i] = std::clamp(right, -32767, 32767);
}
for (u32 i = 0; i < 3 * 32; ++i)
@ -626,7 +627,7 @@ void AXWiiUCode::OutputWMSamples(u32* addresses)
u16* out = (u16*)HLEMemory_Get_Pointer(addresses[i]);
for (u32 j = 0; j < 3 * 6; ++j)
{
int sample = MathUtil::Clamp(in[j], -32767, 32767);
int sample = std::clamp(in[j], -32767, 32767);
out[j] = Common::swap16((u16)sample);
}
}

View File

@ -4,6 +4,7 @@
#include "Core/HW/DSPHLE/UCodes/Zelda.h"
#include <algorithm>
#include <array>
#include <map>
@ -1086,7 +1087,7 @@ void ZeldaAudioRenderer::ApplyReverb(bool post_rendering)
for (u16 j = 0; j < 8; ++j)
sample += (s32)buffer[i + j] * rpb.filter_coeffs[j];
sample >>= 15;
buffer[i] = MathUtil::Clamp(sample, -0x8000, 0x7FFF);
buffer[i] = std::clamp(sample, -0x8000, 0x7FFF);
}
};
@ -1526,7 +1527,7 @@ void ZeldaAudioRenderer::Resample(VPB* vpb, const s16* src, MixingBuffer* dst)
dst_sample_unclamped += (s64)2 * coeffs[i] * input[i];
dst_sample_unclamped >>= 16;
dst_sample = (s16)MathUtil::Clamp<s64>(dst_sample_unclamped, -0x8000, 0x7FFF);
dst_sample = (s16)std::clamp<s64>(dst_sample_unclamped, -0x8000, 0x7FFF);
pos += ratio;
}
@ -1764,7 +1765,7 @@ void ZeldaAudioRenderer::DecodeAFC(VPB* vpb, s16* dst, size_t block_count)
s32 sample =
delta * nibbles[i] + yn1 * m_afc_coeffs[idx * 2] + yn2 * m_afc_coeffs[idx * 2 + 1];
sample >>= 11;
sample = MathUtil::Clamp(sample, -0x8000, 0x7fff);
sample = std::clamp(sample, -0x8000, 0x7fff);
*dst++ = (s16)sample;
yn2 = yn1;
yn1 = sample;

View File

@ -4,10 +4,10 @@
#pragma once
#include <algorithm>
#include <array>
#include "Common/CommonTypes.h"
#include "Common/MathUtil.h"
#include "Core/HW/DSPHLE/UCodes/UCodes.h"
namespace DSP
@ -54,7 +54,7 @@ private:
s32 tmp = (u32)(*buf)[i] * (u32)vol;
tmp >>= 16 - B;
(*buf)[i] = (s16)MathUtil::Clamp(tmp, -0x8000, 0x7FFF);
(*buf)[i] = (s16)std::clamp(tmp, -0x8000, 0x7FFF);
}
}
template <size_t N>
@ -96,7 +96,7 @@ private:
while (count--)
{
s32 vol_src = ((s32)*src++ * (s32)vol) >> 15;
*dst++ += MathUtil::Clamp(vol_src, -0x8000, 0x7FFF);
*dst++ += std::clamp(vol_src, -0x8000, 0x7FFF);
}
}

View File

@ -15,7 +15,6 @@
#include "Common/CommonPaths.h"
#include "Common/CommonTypes.h"
#include "Common/File.h"
#include "Common/MathUtil.h"
#include "Common/MsgHandler.h"
#include "Common/StringUtil.h"
#include "Common/Swap.h"
@ -609,8 +608,8 @@ u16 BlockAlloc::NextFreeBlock(u16 MaxBlock, u16 StartingBlock) const
{
if (m_free_blocks > 0)
{
StartingBlock = MathUtil::Clamp<u16>(StartingBlock, MC_FST_BLOCKS, BAT_SIZE + MC_FST_BLOCKS);
MaxBlock = MathUtil::Clamp<u16>(MaxBlock, MC_FST_BLOCKS, BAT_SIZE + MC_FST_BLOCKS);
StartingBlock = std::clamp<u16>(StartingBlock, MC_FST_BLOCKS, BAT_SIZE + MC_FST_BLOCKS);
MaxBlock = std::clamp<u16>(MaxBlock, MC_FST_BLOCKS, BAT_SIZE + MC_FST_BLOCKS);
for (u16 i = StartingBlock; i < MaxBlock; ++i)
if (m_map[i - MC_FST_BLOCKS] == 0)
return i;

View File

@ -314,9 +314,9 @@ int CSIDevice_GBA::RunBuffer(u8* buffer, int length)
m_last_cmd = buffer[0];
m_timestamp_sent = CoreTiming::GetTicks();
m_next_action = NextAction::WaitTransferTime;
[[fallthrough]];
}
// [[fallthrough]]b
case NextAction::WaitTransferTime:
{
int elapsed_time = static_cast<int>(CoreTiming::GetTicks() - m_timestamp_sent);
@ -324,9 +324,9 @@ int CSIDevice_GBA::RunBuffer(u8* buffer, int length)
if (GetTransferTime(m_last_cmd) > elapsed_time)
return 0;
m_next_action = NextAction::ReceiveResponse;
[[fallthrough]];
}
// [[fallthrough]]
case NextAction::ReceiveResponse:
{
int num_data_received = m_sock_server.Receive(buffer);

View File

@ -4,11 +4,12 @@
// Adapted from in_cube by hcs & destop
#include <algorithm>
#include "Core/HW/StreamADPCM.h"
#include "Common/ChunkFile.h"
#include "Common/CommonTypes.h"
#include "Common/MathUtil.h"
namespace StreamADPCM
{
@ -30,7 +31,7 @@ static s16 ADPDecodeSample(s32 bits, s32 q, s32& hist1, s32& hist2)
hist = (hist1 * 0x62) - (hist2 * 0x37);
break;
}
hist = MathUtil::Clamp((hist + 0x20) >> 6, -0x200000, 0x1fffff);
hist = std::clamp((hist + 0x20) >> 6, -0x200000, 0x1fffff);
s32 cur = (((s16)(bits << 12) >> (q & 0xf)) << 6) + hist;
@ -38,7 +39,7 @@ static s16 ADPDecodeSample(s32 bits, s32 q, s32& hist1, s32& hist2)
hist1 = cur;
cur >>= 6;
cur = MathUtil::Clamp(cur, -0x8000, 0x7fff);
cur = std::clamp(cur, -0x8000, 0x7fff);
return (s16)cur;
}

View File

@ -4,6 +4,7 @@
#include "Core/HW/VideoInterface.h"
#include <algorithm>
#include <array>
#include <cmath>
#include <cstddef>
@ -12,7 +13,6 @@
#include "Common/CommonTypes.h"
#include "Common/Config/Config.h"
#include "Common/Logging/Log.h"
#include "Common/MathUtil.h"
#include "Core/Config/MainSettings.h"
#include "Core/Config/SYSCONFSettings.h"
@ -328,7 +328,7 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
u16 value = static_cast<u16>(1 + m_HTiming0.HLW *
(CoreTiming::GetTicks() - s_ticks_last_line_start) /
(GetTicksPerHalfLine()));
return MathUtil::Clamp(value, static_cast<u16>(1), static_cast<u16>(m_HTiming0.HLW * 2));
return std::clamp<u16>(value, 1, m_HTiming0.HLW * 2);
}),
MMIO::ComplexWrite<u16>([](u32, u16 val) {
WARN_LOG(VIDEOINTERFACE,

View File

@ -4,6 +4,7 @@
#include "Core/HW/WiimoteEmu/Dynamics.h"
#include <algorithm>
#include <cmath>
#include "Common/MathUtil.h"
@ -170,7 +171,7 @@ void EmulateSwing(MotionState* state, ControllerEmu::Force* swing_group, float t
if (y_progress > max_y_progress || y_progress < -1)
{
state->position.y =
MathUtil::Clamp(state->position.y, -1.f * max_distance, max_y_progress * max_distance);
std::clamp(state->position.y, -1.f * max_distance, max_y_progress * max_distance);
state->velocity.y = 0;
state->acceleration.y = 0;
}
@ -184,9 +185,9 @@ WiimoteCommon::DataReportBuilder::AccelData ConvertAccelData(const Common::Vec3&
// 10-bit integers.
constexpr long MAX_VALUE = (1 << 10) - 1;
return {u16(MathUtil::Clamp(std::lround(scaled_accel.x + zero_g), 0l, MAX_VALUE)),
u16(MathUtil::Clamp(std::lround(scaled_accel.y + zero_g), 0l, MAX_VALUE)),
u16(MathUtil::Clamp(std::lround(scaled_accel.z + zero_g), 0l, MAX_VALUE))};
return {u16(std::clamp(std::lround(scaled_accel.x + zero_g), 0l, MAX_VALUE)),
u16(std::clamp(std::lround(scaled_accel.y + zero_g), 0l, MAX_VALUE)),
u16(std::clamp(std::lround(scaled_accel.z + zero_g), 0l, MAX_VALUE))};
}
void EmulateCursor(MotionState* state, ControllerEmu::Cursor* ir_group, float time_elapsed)

View File

@ -4,6 +4,7 @@
#include "Core/HW/WiimoteEmu/Extension/Nunchuk.h"
#include <algorithm>
#include <array>
#include <cassert>
#include <cstring>

View File

@ -642,9 +642,9 @@ void MotionPlus::PrepareInput(const Common::Vec3& angular_velocity)
mplus_data.pitch_slow = (std::abs(pitch) < SLOW_MAX_RAD_PER_SEC);
s32 pitch_value = pitch * (mplus_data.pitch_slow ? SLOW_SCALE : FAST_SCALE);
yaw_value = MathUtil::Clamp(yaw_value + ZERO_VALUE, 0, MAX_VALUE);
roll_value = MathUtil::Clamp(roll_value + ZERO_VALUE, 0, MAX_VALUE);
pitch_value = MathUtil::Clamp(pitch_value + ZERO_VALUE, 0, MAX_VALUE);
yaw_value = std::clamp(yaw_value + ZERO_VALUE, 0, MAX_VALUE);
roll_value = std::clamp(roll_value + ZERO_VALUE, 0, MAX_VALUE);
pitch_value = std::clamp(pitch_value + ZERO_VALUE, 0, MAX_VALUE);
// Bits 0-7
mplus_data.yaw1 = u8(yaw_value);

View File

@ -186,7 +186,7 @@ IPCCommandResult WFSI::IOCtl(const IOCtlRequest& request)
case IOCTL_WFSI_PREPARE_PROFILE:
m_base_extract_path = StringFromFormat("/vol/%s/tmp/", m_device_name.c_str());
// Fall through intended.
[[fallthrough]];
case IOCTL_WFSI_PREPARE_CONTENT:
{

View File

@ -2,6 +2,7 @@
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include <algorithm>
#include <tuple>
#include <type_traits>
#include <utility>
@ -63,7 +64,7 @@ SType ScaleAndClamp(double ps, u32 stScale)
float min = (float)std::numeric_limits<SType>::min();
float max = (float)std::numeric_limits<SType>::max();
return (SType)MathUtil::Clamp(convPS, min, max);
return (SType)std::clamp(convPS, min, max);
}
template <typename T>

View File

@ -426,8 +426,7 @@ ARM64Reg Arm64FPRCache::R(size_t preg, RegType type)
// Else convert this register back to doubles.
m_float_emit->FCVTL(64, EncodeRegToDouble(host_reg), EncodeRegToDouble(host_reg));
reg.Load(host_reg, REG_REG);
// fall through
[[fallthrough]];
}
case REG_REG: // already in a reg
{
@ -442,8 +441,7 @@ ARM64Reg Arm64FPRCache::R(size_t preg, RegType type)
// Else convert this register back to a double.
m_float_emit->FCVT(64, 32, EncodeRegToDouble(host_reg), EncodeRegToDouble(host_reg));
reg.Load(host_reg, REG_LOWER_PAIR);
// fall through
[[fallthrough]];
}
case REG_LOWER_PAIR:
{
@ -476,8 +474,7 @@ ARM64Reg Arm64FPRCache::R(size_t preg, RegType type)
m_float_emit->FCVT(64, 32, EncodeRegToDouble(host_reg), EncodeRegToDouble(host_reg));
reg.Load(host_reg, REG_DUP);
// fall through
[[fallthrough]];
}
case REG_DUP:
{
@ -549,7 +546,7 @@ ARM64Reg Arm64FPRCache::RW(size_t preg, RegType type)
case REG_REG_SINGLE:
flush_reg = GetReg();
m_float_emit->FCVTL(64, EncodeRegToDouble(flush_reg), EncodeRegToDouble(host_reg));
// fall through
[[fallthrough]];
case REG_REG:
// We are doing a full 128bit store because it takes 2 cycles on a Cortex-A57 to do a 128bit
// store.
@ -559,7 +556,7 @@ ARM64Reg Arm64FPRCache::RW(size_t preg, RegType type)
case REG_DUP_SINGLE:
flush_reg = GetReg();
m_float_emit->FCVT(64, 32, EncodeRegToDouble(flush_reg), EncodeRegToDouble(host_reg));
// fall through
[[fallthrough]];
case REG_DUP:
// Store PSR1 (which is equal to PSR0) in memory.
m_float_emit->STR(64, INDEX_UNSIGNED, flush_reg, PPC_REG, PPCSTATE_OFF(ps[preg].ps1));

View File

@ -189,8 +189,8 @@ bool RenderWidget::event(QEvent* event)
case QEvent::MouseMove:
if (g_Config.bFreeLook)
OnFreeLookMouseMove(static_cast<QMouseEvent*>(event));
[[fallthrough]];
// [[fallthrough]]
case QEvent::MouseButtonPress:
if (!Settings::Instance().GetHideCursor() && isActiveWindow())
{

View File

@ -109,7 +109,7 @@ Cursor::StateData Cursor::GetState(const bool adjusted)
// Smooth out z movement:
// FYI: Not using relative input for Z.
m_state.z += MathUtil::Clamp(z - m_state.z, -max_z_step, max_z_step);
m_state.z += std::clamp(z - m_state.z, -max_z_step, max_z_step);
// Relative input:
if (m_relative_setting.GetValue())
@ -122,8 +122,8 @@ Cursor::StateData Cursor::GetState(const bool adjusted)
}
else
{
m_state.x = MathUtil::Clamp(m_state.x + input.x * max_step, -1.0, 1.0);
m_state.y = MathUtil::Clamp(m_state.y + input.y * max_step, -1.0, 1.0);
m_state.x = std::clamp(m_state.x + input.x * max_step, -1.0, 1.0);
m_state.y = std::clamp(m_state.y + input.y * max_step, -1.0, 1.0);
}
}
// Absolute input:

View File

@ -4,6 +4,7 @@
#include "InputCommon/ControllerEmu/StickGate.h"
#include <algorithm>
#include <cmath>
#include "Common/Common.h"
@ -277,8 +278,8 @@ ReshapableInput::ReshapeData ReshapableInput::Reshape(ControlState x, ControlSta
// Scale to the gate shape/radius:
dist *= gate_max_dist;
return {MathUtil::Clamp(std::cos(angle) * dist, -1.0, 1.0),
MathUtil::Clamp(std::sin(angle) * dist, -1.0, 1.0)};
return {std::clamp(std::cos(angle) * dist, -1.0, 1.0),
std::clamp(std::sin(angle) * dist, -1.0, 1.0)};
}
} // namespace ControllerEmu

View File

@ -2,6 +2,7 @@
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include <algorithm>
#include <array>
#include <cstdlib>
#include <fcntl.h>
@ -15,7 +16,6 @@
#include <vector>
#include "Common/FileUtil.h"
#include "Common/MathUtil.h"
#include "Common/StringUtil.h"
#include "InputCommon/ControllerInterface/ControllerInterface.h"
#include "InputCommon/ControllerInterface/Pipes/Pipes.h"
@ -123,7 +123,7 @@ void PipeDevice::AddAxis(const std::string& name, double value)
void PipeDevice::SetAxis(const std::string& entry, double value)
{
value = MathUtil::Clamp(value, 0.0, 1.0);
value = std::clamp(value, 0.0, 1.0);
double hi = std::max(0.0, value - 0.5) * 2.0;
double lo = (0.5 - std::min(0.5, value)) * 2.0;
auto search_hi = m_axes.find(entry + " +");

View File

@ -2,6 +2,7 @@
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include <algorithm>
#include <cstring>
#include <fcntl.h>
#include <libudev.h>

View File

@ -4,6 +4,7 @@
#include "VideoBackends/D3D/Render.h"
#include <algorithm>
#include <array>
#include <cinttypes>
#include <cmath>

View File

@ -514,7 +514,7 @@ static u32 GammaCorrection(u32 color, const float gamma_rcp)
for (int i = BLU_C; i <= RED_C; i++)
{
out_color[i] = static_cast<u8>(
MathUtil::Clamp(std::pow(in_colors[i] / 255.0f, gamma_rcp) * 255.0f, 0.0f, 255.0f));
std::clamp(std::pow(in_colors[i] / 255.0f, gamma_rcp) * 255.0f, 0.0f, 255.0f));
}
u32 out_color32;

View File

@ -77,7 +77,7 @@ static void Draw(s32 x, s32 y, s32 xi, s32 yi)
float dx = vertexOffsetX + (float)(x - vertex0X);
float dy = vertexOffsetY + (float)(y - vertex0Y);
s32 z = (s32)MathUtil::Clamp<float>(ZSlope.GetValue(dx, dy), 0.0f, 16777215.0f);
s32 z = (s32)std::clamp<float>(ZSlope.GetValue(dx, dy), 0.0f, 16777215.0f);
if (bpmem.UseEarlyDepthTest() && g_ActiveConfig.bZComploc)
{

View File

@ -2,11 +2,11 @@
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include <algorithm>
#include <cmath>
#include "Common/ChunkFile.h"
#include "Common/CommonTypes.h"
#include "Common/MathUtil.h"
#include "VideoBackends/Software/DebugUtil.h"
#include "VideoBackends/Software/EfbInterface.h"
#include "VideoBackends/Software/Tev.h"
@ -777,7 +777,7 @@ void Tev::Draw()
// Based on that, choose the index such that points which are far away from the z-axis use the
// 10th "k" value and such that central points use the first value.
float floatindex = 9.f - std::abs(offset) * 9.f;
floatindex = MathUtil::Clamp(floatindex, 0.f, 9.f); // TODO: This shouldn't be necessary!
floatindex = std::clamp(floatindex, 0.f, 9.f); // TODO: This shouldn't be necessary!
// Get the two closest integer indices, look up the corresponding samples
const int indexlower = (int)floatindex;
@ -798,7 +798,7 @@ void Tev::Draw()
ze -= bpmem.fog.GetC();
// clamp 0 to 1
float fog = MathUtil::Clamp(ze, 0.f, 1.f);
float fog = std::clamp(ze, 0.f, 1.f);
switch (bpmem.fog.c_proj_fsel.fsel)
{

View File

@ -12,7 +12,6 @@
#include "Common/Assert.h"
#include "Common/CommonTypes.h"
#include "Common/Logging/Log.h"
#include "Common/MathUtil.h"
#include "Common/MsgHandler.h"
#include "Common/Swap.h"
@ -192,8 +191,8 @@ static void TransformTexCoordRegular(const TexMtxInfo& texinfo, int coordNum, bo
// Makes differences in Rogue Squadron 3 (Hoth sky) and The Last Story (shadow culling)
if (dst->z == 0.0f)
{
dst->x = MathUtil::Clamp(dst->x / 2.0f, -1.0f, 1.0f);
dst->y = MathUtil::Clamp(dst->y / 2.0f, -1.0f, 1.0f);
dst->x = std::clamp(dst->x / 2.0f, -1.0f, 1.0f);
dst->y = std::clamp(dst->y / 2.0f, -1.0f, 1.0f);
}
}
@ -359,9 +358,9 @@ void TransformColor(const InputVertexData* src, OutputVertexData* dst)
LightColor(dst->mvPosition, dst->normal[0], i, colorchan, lightCol);
}
int light_x = MathUtil::Clamp(static_cast<int>(lightCol.x), 0, 255);
int light_y = MathUtil::Clamp(static_cast<int>(lightCol.y), 0, 255);
int light_z = MathUtil::Clamp(static_cast<int>(lightCol.z), 0, 255);
int light_x = std::clamp(static_cast<int>(lightCol.x), 0, 255);
int light_y = std::clamp(static_cast<int>(lightCol.y), 0, 255);
int light_z = std::clamp(static_cast<int>(lightCol.z), 0, 255);
chancolor[1] = (matcolor[1] * (light_x + (light_x >> 7))) >> 8;
chancolor[2] = (matcolor[2] * (light_y + (light_y >> 7))) >> 8;
chancolor[3] = (matcolor[3] * (light_z + (light_z >> 7))) >> 8;
@ -393,7 +392,7 @@ void TransformColor(const InputVertexData* src, OutputVertexData* dst)
LightAlpha(dst->mvPosition, dst->normal[0], i, alphachan, lightCol);
}
int light_a = MathUtil::Clamp(static_cast<int>(lightCol), 0, 255);
int light_a = std::clamp(static_cast<int>(lightCol), 0, 255);
chancolor[0] = (matcolor[0] * (light_a + (light_a >> 7))) >> 8;
}
else

View File

@ -267,10 +267,10 @@ bool SwapChain::CreateSwapChain()
size.width = std::max(g_renderer->GetBackbufferWidth(), 1);
size.height = std::max(g_renderer->GetBackbufferHeight(), 1);
}
size.width = MathUtil::Clamp(size.width, surface_capabilities.minImageExtent.width,
surface_capabilities.maxImageExtent.width);
size.height = MathUtil::Clamp(size.height, surface_capabilities.minImageExtent.height,
surface_capabilities.maxImageExtent.height);
size.width = std::clamp(size.width, surface_capabilities.minImageExtent.width,
surface_capabilities.maxImageExtent.width);
size.height = std::clamp(size.height, surface_capabilities.minImageExtent.height,
surface_capabilities.maxImageExtent.height);
// Prefer identity transform if possible
VkSurfaceTransformFlagBitsKHR transform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;

View File

@ -2,6 +2,8 @@
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include <algorithm>
#include "Common/CommonTypes.h"
#include "Common/Logging/Log.h"
@ -90,8 +92,8 @@ void SetViewport()
{
// There's no way to support oversized depth ranges in this situation. Let's just clamp the
// range to the maximum value supported by the console GPU and hope for the best.
min_depth = MathUtil::Clamp(min_depth, 0.0f, GX_MAX_DEPTH);
max_depth = MathUtil::Clamp(max_depth, 0.0f, GX_MAX_DEPTH);
min_depth = std::clamp(min_depth, 0.0f, GX_MAX_DEPTH);
max_depth = std::clamp(max_depth, 0.0f, GX_MAX_DEPTH);
}
if (g_renderer->UseVertexDepthRange())
@ -131,10 +133,10 @@ void SetViewport()
{
const float max_width = static_cast<float>(g_renderer->GetCurrentFramebuffer()->GetWidth());
const float max_height = static_cast<float>(g_renderer->GetCurrentFramebuffer()->GetHeight());
x = MathUtil::Clamp(x, 0.0f, max_width - 1.0f);
y = MathUtil::Clamp(y, 0.0f, max_height - 1.0f);
width = MathUtil::Clamp(width, 1.0f, max_width - x);
height = MathUtil::Clamp(height, 1.0f, max_height - y);
x = std::clamp(x, 0.0f, max_width - 1.0f);
y = std::clamp(y, 0.0f, max_height - 1.0f);
width = std::clamp(width, 1.0f, max_width - x);
height = std::clamp(height, 1.0f, max_height - y);
}
// Lower-left flip.

View File

@ -14,6 +14,7 @@
#include "VideoCommon/RenderBase.h"
#include <algorithm>
#include <cinttypes>
#include <cmath>
#include <memory>
@ -218,11 +219,11 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
if (bpmem.zcontrol.pixel_format == PEControl::RGB565_Z16)
{
// if Z is in 16 bit format you must return a 16 bit integer
ret = MathUtil::Clamp<u32>(static_cast<u32>(depth * 65536.0f), 0, 0xFFFF);
ret = std::clamp<u32>(static_cast<u32>(depth * 65536.0f), 0, 0xFFFF);
}
else
{
ret = MathUtil::Clamp<u32>(static_cast<u32>(depth * 16777216.0f), 0, 0xFFFFFF);
ret = std::clamp<u32>(static_cast<u32>(depth * 16777216.0f), 0, 0xFFFFFF);
}
return ret;

View File

@ -556,7 +556,7 @@ static void SetSamplerState(u32 index, float custom_tex_scale, bool custom_tex,
// distance they kick in at is important to preserve at any resolution.
// Correct this with the upscaling factor of custom textures.
s64 lod_offset = std::log2(g_renderer->GetEFBScale() / custom_tex_scale) * 256.f;
state.lod_bias = MathUtil::Clamp<s64>(state.lod_bias + lod_offset, -32768, 32767);
state.lod_bias = std::clamp<s64>(state.lod_bias + lod_offset, -32768, 32767);
// Anisotropic also pushes mips farther away so it cannot be used either
state.anisotropic_filtering = 0;

View File

@ -7,7 +7,6 @@
#include <cstddef>
#include "Common/CommonTypes.h"
#include "Common/MathUtil.h"
#include "Common/MsgHandler.h"
#include "Common/Swap.h"
@ -705,9 +704,9 @@ void TexDecoder_DecodeTexel(u8* dst, const u8* src, int s, int t, int imageWidth
// We do the inverse BT.601 conversion for YCbCr to RGB
// http://www.equasys.de/colorconversion.html#YCbCr-RGBColorFormatConversion
u8 R = MathUtil::Clamp(int(1.164f * Y + 1.596f * V), 0, 255);
u8 G = MathUtil::Clamp(int(1.164f * Y - 0.392f * U - 0.813f * V), 0, 255);
u8 B = MathUtil::Clamp(int(1.164f * Y + 2.017f * U), 0, 255);
u8 R = std::clamp(int(1.164f * Y + 1.596f * V), 0, 255);
u8 G = std::clamp(int(1.164f * Y - 0.392f * U - 0.813f * V), 0, 255);
u8 B = std::clamp(int(1.164f * Y + 2.017f * U), 0, 255);
dst[t * imageWidth + s] = 0xff000000 | B << 16 | G << 8 | R;
}
break;
@ -770,13 +769,13 @@ void TexDecoder_DecodeXFB(u8* dst, const u8* src, u32 width, u32 height, u32 str
// We do the inverse BT.601 conversion for YCbCr to RGB
// http://www.equasys.de/colorconversion.html#YCbCr-RGBColorFormatConversion
u8 R1 = static_cast<u8>(MathUtil::Clamp(int(1.164f * Y1 + 1.596f * V), 0, 255));
u8 G1 = static_cast<u8>(MathUtil::Clamp(int(1.164f * Y1 - 0.392f * U - 0.813f * V), 0, 255));
u8 B1 = static_cast<u8>(MathUtil::Clamp(int(1.164f * Y1 + 2.017f * U), 0, 255));
u8 R1 = static_cast<u8>(std::clamp(int(1.164f * Y1 + 1.596f * V), 0, 255));
u8 G1 = static_cast<u8>(std::clamp(int(1.164f * Y1 - 0.392f * U - 0.813f * V), 0, 255));
u8 B1 = static_cast<u8>(std::clamp(int(1.164f * Y1 + 2.017f * U), 0, 255));
u8 R2 = static_cast<u8>(MathUtil::Clamp(int(1.164f * Y2 + 1.596f * V), 0, 255));
u8 G2 = static_cast<u8>(MathUtil::Clamp(int(1.164f * Y2 - 0.392f * U - 0.813f * V), 0, 255));
u8 B2 = static_cast<u8>(MathUtil::Clamp(int(1.164f * Y2 + 2.017f * U), 0, 255));
u8 R2 = static_cast<u8>(std::clamp(int(1.164f * Y2 + 1.596f * V), 0, 255));
u8 G2 = static_cast<u8>(std::clamp(int(1.164f * Y2 - 0.392f * U - 0.813f * V), 0, 255));
u8 B2 = static_cast<u8>(std::clamp(int(1.164f * Y2 + 2.017f * U), 0, 255));
u32 rgba = 0xff000000 | B1 << 16 | G1 << 8 | R1;
std::memcpy(dst_ptr, &rgba, sizeof(rgba));

View File

@ -9,7 +9,6 @@
#include "Common/CPUDetect.h"
#include "Common/CommonTypes.h"
#include "Common/Intrinsics.h"
#include "Common/MathUtil.h"
#include "Common/MsgHandler.h"
#include "Common/Swap.h"

View File

@ -6,18 +6,6 @@
#include "Common/MathUtil.h"
TEST(MathUtil, Clamp)
{
EXPECT_EQ(1, MathUtil::Clamp(1, 0, 2));
EXPECT_EQ(1.0, MathUtil::Clamp(1.0, 0.0, 2.0));
EXPECT_EQ(2, MathUtil::Clamp(4, 0, 2));
EXPECT_EQ(2.0, MathUtil::Clamp(4.0, 0.0, 2.0));
EXPECT_EQ(0, MathUtil::Clamp(-1, 0, 2));
EXPECT_EQ(0.0, MathUtil::Clamp(-1.0, 0.0, 2.0));
}
TEST(MathUtil, IntLog2)
{
EXPECT_EQ(0, IntLog2(1));