Skip to content

Instantly share code, notes, and snippets.

@valpackett
Created January 3, 2020 12:03
Show Gist options
  • Select an option

  • Save valpackett/17d7842c7601e8db06de57a2d5a0b7d7 to your computer and use it in GitHub Desktop.

Select an option

Save valpackett/17d7842c7601e8db06de57a2d5a0b7d7 to your computer and use it in GitHub Desktop.

Revisions

  1. valpackett created this gist Jan 3, 2020.
    448 changes: 448 additions & 0 deletions wf-alias-optional.patch
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,448 @@
    diff --git i/include/wayfire/config/option-types.hpp w/include/wayfire/config/option-types.hpp
    index ec49728..7e30648 100644
    --- i/include/wayfire/config/option-types.hpp
    +++ w/include/wayfire/config/option-types.hpp
    @@ -1,12 +1,24 @@
    #pragma once

    +#if __has_include(<optional>)
    +#include <optional>
    +#else
    #include <experimental/optional>
    +#endif
    #include <string>

    namespace wf
    {
    namespace option_type
    {
    +
    +template <class Type>
    +#if __has_include(<optional>)
    +using optional = std::optional<Type>;
    +#else
    +using optional = std::experimental::optional<Type>;
    +#endif
    +
    /**
    * To create an option of a given type, from_string must be specialized for
    * parsing the type.
    @@ -14,7 +26,7 @@ namespace option_type
    * @param string The string representation of the value.
    * @return The parsed value, if the string was valid.
    */
    -template<class Type> std::experimental::optional<Type> from_string(
    +template<class Type> optional<Type> from_string(
    const std::string& string);

    /**
    diff --git i/include/wayfire/config/option.hpp w/include/wayfire/config/option.hpp
    index 6ee1cf7..5df42e9 100644
    --- i/include/wayfire/config/option.hpp
    +++ w/include/wayfire/config/option.hpp
    @@ -96,20 +96,20 @@ class bounded_option_base_t<Type, true>
    {
    public:
    /** @return The minimal permissible value for this option, if it is set. */
    - std::experimental::optional<Type> get_minimum() const
    + wf::option_type::optional<Type> get_minimum() const
    {
    return minimum;
    }

    /** @return The maximal permissible value for this option, if it is set. */
    - std::experimental::optional<Type> get_maximum() const
    + wf::option_type::optional<Type> get_maximum() const
    {
    return maximum;
    }

    protected:
    - std::experimental::optional<Type> minimum;
    - std::experimental::optional<Type> maximum;
    + wf::option_type::optional<Type> minimum;
    + wf::option_type::optional<Type> maximum;

    /**
    * @return The closest possible value
    diff --git i/include/wayfire/config/types.hpp w/include/wayfire/config/types.hpp
    index 66308ed..33813d1 100644
    --- i/include/wayfire/config/types.hpp
    +++ w/include/wayfire/config/types.hpp
    @@ -15,7 +15,7 @@ namespace option_type
    * @param string The string representation of the value.
    * @return The parsed value, if the string was valid.
    */
    -template<class Type> std::experimental::optional<Type> from_string(
    +template<class Type> optional<Type> from_string(
    const std::string& string);

    /**
    @@ -29,7 +29,7 @@ template<class Type> std::string to_string(const Type& value);
    /**
    * Parse the given string as a signed 32-bit integer in decimal system.
    */
    -template<> std::experimental::optional<int>
    +template<> optional<int>
    from_string<int>(const std::string&);

    /**
    @@ -37,20 +37,20 @@ template<> std::experimental::optional<int>
    * Truthy values are "True" (any capitalization) and 1.
    * False values are "False" (any capitalization) and 0.
    */
    -template<> std::experimental::optional<bool>
    +template<> optional<bool>
    from_string<bool>(const std::string&);

    /**
    * Parse the given string as a signed 64-bit floating point number.
    */
    -template<> std::experimental::optional<double>
    +template<> optional<double>
    from_string<double>(const std::string&);

    /**
    * Parse the string as a string.
    * The string should not contain newline characters.
    */
    -template<> std::experimental::optional<std::string>
    +template<> optional<std::string>
    from_string<std::string>(const std::string&);

    /**
    @@ -121,7 +121,7 @@ namespace option_type
    * Create a new color value from the given hex string, format is either
    * #RRGGBBAA or #RGBA.
    */
    -template<> std::experimental::optional<color_t>
    +template<> optional<color_t>
    from_string(const std::string& value);

    /** Convert the color to its hex string representation. */
    @@ -188,7 +188,7 @@ namespace option_type
    * Special cases are "none" and "disabled", which result in modifiers and
    * key 0.
    */
    -template<> std::experimental::optional<keybinding_t> from_string(
    +template<> optional<keybinding_t> from_string(
    const std::string& description);

    /** Represent the keybinding as a string. */
    @@ -232,7 +232,7 @@ namespace option_type
    * Special case are descriptions "none" and "disable", which result in
    * mod = button = 0
    */
    -template<> std::experimental::optional<buttonbinding_t> from_string(
    +template<> optional<buttonbinding_t> from_string(
    const std::string& description);

    /** Represent the buttonbinding as a string. */
    @@ -325,7 +325,7 @@ namespace option_type
    * 3. [edge-]swipe up-left|right-down|... <fingercount>
    * 4. disable | none
    */
    -template<> std::experimental::optional<touchgesture_t> from_string(
    +template<> optional<touchgesture_t> from_string(
    const std::string& description);

    /** Represent the touch gesture as a string. */
    @@ -380,7 +380,7 @@ namespace option_type
    * The string consists of valid descriptions of keybindings, buttonbindings
    * and touch gestures, separated by a single '|' sign.
    */
    -template<> std::experimental::optional<activatorbinding_t> from_string(
    +template<> optional<activatorbinding_t> from_string(
    const std::string& string);

    /** Represent the activator binding as a string. */
    diff --git i/include/wayfire/config/xml.hpp w/include/wayfire/config/xml.hpp
    index 9882970..9a0b1c6 100644
    --- i/include/wayfire/config/xml.hpp
    +++ w/include/wayfire/config/xml.hpp
    @@ -7,7 +7,7 @@
    #include <libxml/parser.h>
    #include <libxml/tree.h>

    -#include <experimental/optional>
    +#include <wayfire/config/option-types.hpp>
    #include <wayfire/config/option.hpp>
    #include <wayfire/config/section.hpp>

    diff --git i/meson.build w/meson.build
    index f860b06..3dde5a8 100644
    --- i/meson.build
    +++ w/meson.build
    @@ -5,7 +5,7 @@ project(
    license: 'MIT',
    meson_version: '>=0.43.0',
    default_options: [
    - 'cpp_std=gnu++14',
    + 'cpp_std=gnu++17',
    'warning_level=2',
    'werror=false',
    ],
    @@ -46,7 +46,8 @@ pkgconfig.generate(
    install_headers([], subdir: 'wayfire/config')

    wfconfig = declare_dependency(link_with: lib_wfconfig,
    - include_directories: wfconfig_inc)
    + include_directories: wfconfig_inc,
    + dependencies: glm)

    # Install headers
    subdir('include')
    diff --git i/src/types.cpp w/src/types.cpp
    index a979d77..dd1978a 100644
    --- i/src/types.cpp
    +++ w/src/types.cpp
    @@ -8,7 +8,7 @@
    #include <sstream>

    /* --------------------------- Primitive types ------------------------------ */
    -template<> std::experimental::optional<bool>
    +template<> wf::option_type::optional<bool>
    wf::option_type::from_string(const std::string& value)
    {
    std::string lowercase = value;
    @@ -24,7 +24,7 @@ template<> std::experimental::optional<bool>
    return {};
    }

    -template<> std::experimental::optional<int>
    +template<> wf::option_type::optional<int>
    wf::option_type::from_string(const std::string& value)
    {
    std::istringstream in{value};
    @@ -38,7 +38,7 @@ template<> std::experimental::optional<int>
    }

    /** Attempt to parse a string as an double value */
    -template<> std::experimental::optional<double>
    +template<> wf::option_type::optional<double>
    wf::option_type::from_string(const std::string& value)
    {
    auto old = std::locale::global(std::locale::classic());
    @@ -56,7 +56,7 @@ template<> std::experimental::optional<double>
    return result;
    }

    -template<> std::experimental::optional<std::string>
    +template<> wf::option_type::optional<std::string>
    wf::option_type::from_string(const std::string& value)
    {
    if (value.find_first_of("\n\r") != std::string::npos)
    @@ -110,7 +110,7 @@ static double hex_to_double(std::string value)
    return std::strtol(value.c_str(), &dummy, 16);
    }

    -static std::experimental::optional<wf::color_t>
    +static wf::option_type::optional<wf::color_t>
    try_parse_rgba(const std::string& value)
    {
    wf::color_t parsed = {0, 0, 0, 0};
    @@ -127,11 +127,11 @@ static std::experimental::optional<wf::color_t>

    std::locale::global(old);

    - return valid_color ? parsed : std::experimental::optional<wf::color_t>{};
    + return valid_color ? parsed : wf::option_type::optional<wf::color_t>{};
    }

    static const std::string hex_digits = "0123456789ABCDEF";
    -template<> std::experimental::optional<wf::color_t>
    +template<> wf::option_type::optional<wf::color_t>
    wf::option_type::from_string(const std::string& value)
    {
    auto as_rgba = try_parse_rgba(value);
    @@ -291,7 +291,7 @@ static std::string filter_out(std::string value, std::string filter)

    static const std::string whitespace_chars = " \t\n\r\v\b";

    -static std::experimental::optional<general_binding_t>
    +static wf::option_type::optional<general_binding_t>
    parse_binding(std::string binding_description)
    {
    /* Handle disabled bindings */
    @@ -365,7 +365,7 @@ wf::keybinding_t::keybinding_t(uint32_t modifier, uint32_t keyval)
    this->keyval = keyval;
    }

    -template<> std::experimental::optional<wf::keybinding_t>
    +template<> wf::option_type::optional<wf::keybinding_t>
    wf::option_type::from_string(const std::string& description)
    {
    auto parsed_opt = parse_binding(description);
    @@ -419,7 +419,7 @@ wf::buttonbinding_t::buttonbinding_t(uint32_t modifier, uint32_t buttonval)
    this->button = buttonval;
    }

    -template<> std::experimental::optional<wf::buttonbinding_t>
    +template<> wf::option_type::optional<wf::buttonbinding_t>
    wf::option_type::from_string(const std::string& description)
    {
    auto parsed_opt = parse_binding(description);
    @@ -575,7 +575,7 @@ wf::touchgesture_t parse_gesture(const std::string& value)
    return wf::touchgesture_t{wf::GESTURE_TYPE_NONE, 0, 0};
    }

    -template<> std::experimental::optional<wf::touchgesture_t>
    +template<> wf::option_type::optional<wf::touchgesture_t>
    wf::option_type::from_string(const std::string& description)
    {
    auto as_binding = parse_binding(description);
    @@ -699,7 +699,7 @@ template<class Type> bool try_add_binding(
    return false;
    }

    -template<> std::experimental::optional<wf::activatorbinding_t>
    +template<> wf::option_type::optional<wf::activatorbinding_t>
    wf::option_type::from_string(const std::string& string)
    {
    activatorbinding_t binding;
    diff --git i/src/xml.cpp w/src/xml.cpp
    index a272b99..3b79aa2 100644
    --- i/src/xml.cpp
    +++ w/src/xml.cpp
    @@ -29,10 +29,10 @@ class xml_section_t : public wf::config::section_t, public xml_derived_element_t
    using wf::config::section_t::section_t;
    };

    -static std::experimental::optional<const xmlChar*>
    +static wf::option_type::optional<const xmlChar*>
    extract_value(xmlNodePtr node, std::string value_name)
    {
    - std::experimental::optional<const xmlChar*> value_ptr;
    + wf::option_type::optional<const xmlChar*> value_ptr;

    auto child_ptr = node->children;
    while (child_ptr != nullptr)
    @@ -79,8 +79,8 @@ enum bounds_error_t

    template<class T> bounds_error_t set_bounds(
    std::shared_ptr<wf::config::option_base_t>& option,
    - std::experimental::optional<const xmlChar*> min_ptr,
    - std::experimental::optional<const xmlChar*> max_ptr)
    + wf::option_type::optional<const xmlChar*> min_ptr,
    + wf::option_type::optional<const xmlChar*> max_ptr)
    {
    if (!option)
    return BOUNDS_OK; // there has been an earlier error
    @@ -102,7 +102,7 @@ template<class T> bounds_error_t set_bounds(

    if (max_ptr)
    {
    - std::experimental::optional<T> value = wf::option_type::from_string<T>(
    + wf::option_type::optional<T> value = wf::option_type::from_string<T>(
    (const char*)max_ptr.value());
    if (value) {
    typed_option->set_maximum(value.value());
    diff --git i/test/meson.build w/test/meson.build
    index 0260ad6..35612c2 100644
    --- i/test/meson.build
    +++ w/test/meson.build
    @@ -1,40 +1,35 @@
    types_test = executable(
    'types_test',
    'types_test.cpp',
    - include_directories: wfconfig_inc,
    - link_with: lib_wfconfig,
    + dependencies: wfconfig,
    install: false)
    test('Types test', types_test)

    option_base_test = executable(
    'option_base_test',
    'option_base_test.cpp',
    - include_directories: wfconfig_inc,
    - link_with: lib_wfconfig,
    + dependencies: wfconfig,
    install: false)
    test('OptionBase test', option_base_test)

    option_test = executable(
    'option_test',
    'option_test.cpp',
    - include_directories: wfconfig_inc,
    - link_with: lib_wfconfig,
    + dependencies: wfconfig,
    install: false)
    test('Option test', option_test)

    option_wrapper_test = executable(
    'option_wrapper_test',
    'option_wrapper_test.cpp',
    - include_directories: wfconfig_inc,
    - link_with: lib_wfconfig,
    + dependencies: wfconfig,
    install: false)
    test('Option wrapper test', option_wrapper_test)

    section_test = executable(
    'section_test',
    'section_test.cpp',
    - include_directories: wfconfig_inc,
    - link_with: lib_wfconfig,
    + dependencies: wfconfig,
    install: false)
    test('Section test', section_test)

    @@ -42,24 +37,21 @@ xml_test = executable(
    'xml_test',
    'xml_test.cpp',
    include_directories: wfconfig_inc,
    - link_with: lib_wfconfig,
    - dependencies: libxml2,
    + dependencies: [wfconfig, libxml2],
    install: false)
    test('XML test', xml_test)

    config_manager_test = executable(
    'config_manager_test',
    'config_manager_test.cpp',
    - include_directories: wfconfig_inc,
    - link_with: lib_wfconfig,
    + dependencies: wfconfig,
    install: false)
    test('ConfigManager test', config_manager_test)

    file_parse_test = executable(
    'file_test',
    'file_test.cpp',
    - include_directories: wfconfig_inc,
    - link_with: lib_wfconfig,
    + dependencies: wfconfig,
    install: false)
    test('File parsing test', file_parse_test)

    @@ -67,15 +59,13 @@ test('File parsing test', file_parse_test)
    log_test = executable(
    'log_test',
    'log_test.cpp',
    - include_directories: wfconfig_inc,
    - link_with: lib_wfconfig,
    + dependencies: wfconfig,
    install: false)
    test('Log test', log_test)

    duration_test = executable(
    'duration_test',
    'duration_test.cpp',
    - include_directories: wfconfig_inc,
    - link_with: lib_wfconfig,
    + dependencies: wfconfig,
    install: false)
    test('Duration test', duration_test)
    diff --git i/test/types_test.cpp w/test/types_test.cpp
    index 58b5e3e..c84fdc5 100644
    --- i/test/types_test.cpp
    +++ w/test/types_test.cpp
    @@ -80,7 +80,7 @@ static void check_color_equals(const wf::color_t& color,
    }

    static void check_color_equals(
    - const std::experimental::optional<wf::color_t>& color,
    + const wf::option_type::optional<wf::color_t>& color,
    double r, double g, double b, double a)
    {
    check_color_equals(color.value(), r, g, b, a);