b603929214
## Summary of the Pull Request Introduces `IInheritable` as an interface that helps move cascading settings into the Terminal Settings Model. `GlobalAppSettings` and `Profile` both are now `IInheritable`. `CascadiaSettings` was updated to `CreateChild()` for globals and each profile when we are loading the JSON data. IInheritable does most of the heavy lifting. It introduces a two new macros and the interface. The macros help implement the fallback functionality for nullable and non-nullable settings. ## References #7876 - Spec Addendum #6904 - TSM Spec #1564 - Settings UI #7876 - `Copy()` needs to be updated to include _parent
61 lines
2.1 KiB
C++
61 lines
2.1 KiB
C++
// Copyright (c) Microsoft Corporation.
|
|
// Licensed under the MIT license.
|
|
|
|
#pragma once
|
|
|
|
namespace til
|
|
{
|
|
// Method Description:
|
|
// - Base case provided to handle the last argument to coalesce_value<T...>()
|
|
template<typename T>
|
|
T coalesce_value(const T& base)
|
|
{
|
|
return base;
|
|
}
|
|
|
|
// Method Description:
|
|
// - Base case provided to throw an assertion if you call coalesce_value(opt, opt, opt)
|
|
template<typename T>
|
|
T coalesce_value(const std::optional<T>& base)
|
|
{
|
|
static_assert(false, "coalesce_value must be passed a base non-optional value to be used if all optionals are empty");
|
|
return T{};
|
|
}
|
|
|
|
// Method Description:
|
|
// - Returns the value from the first populated optional, or a base value if none were populated.
|
|
template<typename T, typename... Ts>
|
|
T coalesce_value(const std::optional<T>& t1, Ts&&... t2)
|
|
{
|
|
// Initially, I wanted to check "has_value" and short-circuit out so that we didn't
|
|
// evaluate value_or for every single optional, but has_value/value emits exception handling
|
|
// code that value_or doesn't. Less exception handling is cheaper than calling value_or a
|
|
// few more times.
|
|
return t1.value_or(coalesce_value(std::forward<Ts>(t2)...));
|
|
}
|
|
|
|
// Method Description:
|
|
// - Base case provided to handle the last argument to coalesce_value<T...>()
|
|
template<typename T>
|
|
std::optional<T> coalesce(const std::optional<T>& base)
|
|
{
|
|
return base;
|
|
}
|
|
|
|
// Method Description:
|
|
// - Base case provided to handle the last argument to coalesce_value<T...>(..., nullopt)
|
|
template<typename T>
|
|
std::optional<T> coalesce(const std::nullopt_t& base)
|
|
{
|
|
return base;
|
|
}
|
|
|
|
// Method Description:
|
|
// - Returns the value from the first populated optional, or the last one (if none of the previous had a value)
|
|
template<typename T, typename... Ts>
|
|
std::optional<T> coalesce(const std::optional<T>& t1, Ts&&... t2)
|
|
{
|
|
return t1.has_value() ? t1 : coalesce(std::forward<Ts>(t2)...);
|
|
}
|
|
}
|