From 1e551f4e557c498e4d33ddda92ecd1a825c5e244 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Mon, 18 Dec 2017 22:10:01 +0800 Subject: [PATCH 1/8] add check for C++17 constexpr if --- include/nana/c++defines.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/nana/c++defines.hpp b/include/nana/c++defines.hpp index 04b5113f..70db8f8f 100644 --- a/include/nana/c++defines.hpp +++ b/include/nana/c++defines.hpp @@ -199,6 +199,11 @@ # define _enable_std_clamp #endif +#undef _nana_cxx_constexpr_if +#if (defined(_MSC_VER) && (_MSC_VER >= 1912) && defined(_MSVC_LANG) && _MSVC_LANG>= 201703) +# define _nana_cxx_constexpr_if +#endif + #if defined(NANA_WINDOWS) #ifndef _UNICODE From 486e75f3ae63421352b3c82f5849c3ae9492c6c1 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Mon, 18 Dec 2017 22:13:03 +0800 Subject: [PATCH 2/8] apply constexpr if --- include/nana/gui/detail/general_events.hpp | 51 ++++++++++++++++++++-- include/nana/gui/programming_interface.hpp | 28 ++++++++++++ source/gui/widgets/spinbox.cpp | 32 +++++++++++++- 3 files changed, 106 insertions(+), 5 deletions(-) diff --git a/include/nana/gui/detail/general_events.hpp b/include/nana/gui/detail/general_events.hpp index 5992f1a0..c776678a 100644 --- a/include/nana/gui/detail/general_events.hpp +++ b/include/nana/gui/detail/general_events.hpp @@ -1,7 +1,7 @@ /** * Definition of General Events * Nana C++ Library(http://www.nanapro.org) -* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) +* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -133,11 +133,25 @@ namespace nana /// Creates an event handler at the beginning of event chain template event_handle connect_front(Function && fn) - { + { +#ifdef _nana_cxx_constexpr_if + if constexpr(std::is_invocable_v) + { + return _m_emplace(new docker{ this, fn, false }, true); + } + else if constexpr(std::is_invocable_v) + { + return _m_emplace(new docker{ this, [fn](arg_reference) { + fn(); + }, false }, true); + } +#else using prototype = typename std::remove_reference::type; return _m_emplace(new docker(this, factory::value>::build(std::forward(fn)), false), true); +#endif } +#ifndef _nana_cxx_constexpr_if /// It will not get called if stop_propagation() was called. event_handle connect(void (*fn)(arg_reference)) { @@ -145,13 +159,27 @@ namespace nana fn(arg); }); } +#endif /// It will not get called if stop_propagation() was called, because it is set at the end of the chain.. template event_handle connect(Function && fn) { +#ifdef _nana_cxx_constexpr_if + if constexpr(std::is_invocable_v) + { + return _m_emplace(new docker{ this, fn, false }, false); + } + else if constexpr(std::is_invocable_v) + { + return _m_emplace(new docker{ this, [fn](arg_reference){ + fn(); + }, false }, false); + } +#else using prototype = typename std::remove_reference::type; return _m_emplace(new docker(this, factory::value>::build(std::forward(fn)), false), false); +#endif } /// It will not get called if stop_propagation() was called. @@ -164,10 +192,22 @@ namespace nana /// It will get called because it is unignorable. template event_handle connect_unignorable(Function && fn, bool in_front = false) - { + { +#ifdef _nana_cxx_constexpr_if + if constexpr(std::is_invocable_v) + { + return _m_emplace(new docker{ this, fn, true }, in_front); + } + else if constexpr(std::is_invocable_v) + { + return _m_emplace(new docker{ this, [fn](arg_reference) { + fn(); + }, true }, in_front); + } +#else using prototype = typename std::remove_reference::type; - return _m_emplace(new docker(this, factory::value>::build(std::forward(fn)), true), in_front); +#endif } void emit(arg_reference& arg, window window_handle) @@ -210,6 +250,8 @@ namespace nana } } private: + +#ifndef _nana_cxx_constexpr_if template struct factory { @@ -385,6 +427,7 @@ namespace nana }; } }; +#endif }; struct arg_mouse diff --git a/include/nana/gui/programming_interface.hpp b/include/nana/gui/programming_interface.hpp index 8c0d85fe..b5d3e8c2 100644 --- a/include/nana/gui/programming_interface.hpp +++ b/include/nana/gui/programming_interface.hpp @@ -245,6 +245,19 @@ namespace API if (nullptr == general_evt) throw std::invalid_argument("API::events(): bad parameter window handle, no events object or invalid window handle."); +#ifdef _nana_cxx_constexpr_if + if constexpr(std::is_same_v) + { + return *general_evt; + } + else + { + auto * widget_evt = dynamic_cast(general_evt); + if (nullptr == widget_evt) + throw std::invalid_argument("API::events(): bad template parameter Widget, the widget type and window handle do not match."); + return *widget_evt; + } +#else if (std::is_same<::nana::general_events, event_type>::value) return *static_cast(general_evt); @@ -252,6 +265,7 @@ namespace API if (nullptr == widget_evt) throw std::invalid_argument("API::events(): bad template parameter Widget, the widget type and window handle do not match."); return *widget_evt; +#endif } template::value>::type* = nullptr> @@ -278,6 +292,19 @@ namespace API if (nullptr == wdg_colors) throw std::invalid_argument("API::scheme(): bad parameter window handle, no events object or invalid window handle."); +#ifdef _nana_cxx_constexpr_if + if constexpr(std::is_same<::nana::widget_geometrics, scheme_type>::value) + { + return *static_cast(wdg_colors); + } + else + { + auto * comp_wdg_colors = dynamic_cast(wdg_colors); + if (nullptr == comp_wdg_colors) + throw std::invalid_argument("API::scheme(): bad template parameter Widget, the widget type and window handle do not match."); + return *comp_wdg_colors; + } +#else if (std::is_same<::nana::widget_geometrics, scheme_type>::value) return *static_cast(wdg_colors); @@ -285,6 +312,7 @@ namespace API if (nullptr == comp_wdg_colors) throw std::invalid_argument("API::scheme(): bad template parameter Widget, the widget type and window handle do not match."); return *comp_wdg_colors; +#endif } point window_position(window); diff --git a/source/gui/widgets/spinbox.cpp b/source/gui/widgets/spinbox.cpp index 41b592f3..5bf2b342 100644 --- a/source/gui/widgets/spinbox.cpp +++ b/source/gui/widgets/spinbox.cpp @@ -82,10 +82,39 @@ namespace nana bool check_value(const std::string& str) const override { +#ifdef _nana_cxx_constexpr_if + auto i = str.c_str(); + if ('+' == *i || '-' == *i) + ++i; + + if constexpr(std::is_same::value) + { + for (; 0 != *i; ++i) + { + if (*i < '0' || '9' < *i) + return false; + } + } + else + { + bool dot = false; + for (; 0 != *i; ++i) + { + if (('.' == *i) && (!dot)) + { + dot = true; + continue; + } + + if (*i < '0' || '9' < *i) + return false; + } + } +#else if (str.empty()) return true; - auto size = str.size(); + auto const size = str.size(); std::size_t pos = 0; if (str[0] == '+' || str[0] == '-') pos = 1; @@ -115,6 +144,7 @@ namespace nana return false; } } +#endif return true; } From 5f77c73aaafbec8f43f2fe70314978580661c7b2 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Tue, 19 Dec 2017 03:30:38 +0800 Subject: [PATCH 3/8] no throw() --- include/nana/gui/programming_interface.hpp | 2 +- include/nana/gui/widgets/combox.hpp | 2 +- include/nana/gui/widgets/group.hpp | 6 +++--- include/nana/gui/widgets/label.hpp | 4 ++-- include/nana/gui/widgets/spinbox.hpp | 2 +- include/nana/gui/widgets/tabbar.hpp | 2 +- include/nana/gui/widgets/textbox.hpp | 2 +- include/nana/gui/widgets/widget.hpp | 8 ++++---- include/nana/paint/graphics.hpp | 2 +- source/gui/programming_interface.cpp | 2 +- source/gui/widgets/combox.cpp | 2 +- source/gui/widgets/group.cpp | 2 +- source/gui/widgets/label.cpp | 4 ++-- source/gui/widgets/spinbox.cpp | 2 +- source/gui/widgets/tabbar.cpp | 2 +- source/gui/widgets/textbox.cpp | 2 +- source/gui/widgets/widget.cpp | 8 ++++---- source/paint/graphics.cpp | 2 +- 18 files changed, 28 insertions(+), 28 deletions(-) diff --git a/include/nana/gui/programming_interface.hpp b/include/nana/gui/programming_interface.hpp index b5d3e8c2..45ca629c 100644 --- a/include/nana/gui/programming_interface.hpp +++ b/include/nana/gui/programming_interface.hpp @@ -80,7 +80,7 @@ namespace API void set_measurer(window, ::nana::dev::widget_content_measurer_interface*); void attach_drawer(widget&, drawer_trigger&); - ::nana::detail::native_string_type window_caption(window) throw(); + ::nana::detail::native_string_type window_caption(window) noexcept; void window_caption(window, ::nana::detail::native_string_type); window create_window(window, bool nested, const rectangle&, const appearance&, widget* attached); diff --git a/include/nana/gui/widgets/combox.hpp b/include/nana/gui/widgets/combox.hpp index fc8e4522..551c65d3 100644 --- a/include/nana/gui/widgets/combox.hpp +++ b/include/nana/gui/widgets/combox.hpp @@ -223,7 +223,7 @@ namespace nana const drawerbase::combox::drawer_impl& _m_impl() const; private: //Overrides widget's virtual functions - native_string_type _m_caption() const throw() override; + native_string_type _m_caption() const noexcept override; void _m_caption(native_string_type&&) override; nana::any * _m_anyobj(std::size_t pos, bool alloc_if_empty) const override; }; diff --git a/include/nana/gui/widgets/group.hpp b/include/nana/gui/widgets/group.hpp index 2e264289..1bc4d963 100644 --- a/include/nana/gui/widgets/group.hpp +++ b/include/nana/gui/widgets/group.hpp @@ -63,8 +63,8 @@ namespace nana{ group& enable_format_caption(bool format); - group& collocate() throw(); - group& div(const char* div_str) throw(); + group& collocate() noexcept; + group& div(const char* div_str) noexcept; field_reference operator[](const char* field); template @@ -78,7 +78,7 @@ namespace nana{ void _m_add_child(const char* field, widget*); void _m_init(); void _m_complete_creation() override; - native_string_type _m_caption() const throw() override; + native_string_type _m_caption() const noexcept override; void _m_caption(native_string_type&&) override; private: std::unique_ptr impl_; diff --git a/include/nana/gui/widgets/label.hpp b/include/nana/gui/widgets/label.hpp index ee26383b..09d990e4 100644 --- a/include/nana/gui/widgets/label.hpp +++ b/include/nana/gui/widgets/label.hpp @@ -62,12 +62,12 @@ namespace nana label(window parent, const char* text, bool visible = true) :label(parent, std::string(text),visible) {}; label(window, const rectangle& = {}, bool visible = true); label& transparent(bool); ///< Switchs the label widget to the transparent background mode. - bool transparent() const throw(); + bool transparent() const noexcept; label& format(bool); ///< Switches the format mode of the widget. label& add_format_listener(std::function); /// as same as the HTML "for" attribute of a label - label& click_for(window associated_window) throw(); + label& click_for(window associated_window) noexcept; /// Returns the size of the text. If *allowed_width_in_pixel* is not zero, returns a /// "corrected" size that changes lines to fit the text into the specified width diff --git a/include/nana/gui/widgets/spinbox.hpp b/include/nana/gui/widgets/spinbox.hpp index 15cbc694..7815250c 100644 --- a/include/nana/gui/widgets/spinbox.hpp +++ b/include/nana/gui/widgets/spinbox.hpp @@ -113,7 +113,7 @@ namespace nana void modifier(std::string prefix_utf8, std::string suffix_utf8); void modifier(const std::wstring & prefix, const std::wstring& suffix); private: - native_string_type _m_caption() const throw(); + native_string_type _m_caption() const noexcept; void _m_caption(native_string_type&&); }; //end class spinbox }//end namespace nana diff --git a/include/nana/gui/widgets/tabbar.hpp b/include/nana/gui/widgets/tabbar.hpp index 0e2e2e9c..1c492fae 100644 --- a/include/nana/gui/widgets/tabbar.hpp +++ b/include/nana/gui/widgets/tabbar.hpp @@ -384,7 +384,7 @@ namespace nana driver(); ~driver(); - model* get_model() const throw(); + model* get_model() const noexcept; private: //Overrides drawer_trigger's method void attached(widget_reference, graph_reference) override; diff --git a/include/nana/gui/widgets/textbox.hpp b/include/nana/gui/widgets/textbox.hpp index 5f6dbc91..ed8d6c91 100644 --- a/include/nana/gui/widgets/textbox.hpp +++ b/include/nana/gui/widgets/textbox.hpp @@ -276,7 +276,7 @@ namespace nana std::size_t text_line_count() const noexcept; protected: //Overrides widget's virtual functions - native_string_type _m_caption() const throw() override; + native_string_type _m_caption() const noexcept override; void _m_caption(native_string_type&&) override; void _m_typeface(const paint::font&) override; }; diff --git a/include/nana/gui/widgets/widget.hpp b/include/nana/gui/widgets/widget.hpp index 0ee37703..c4834cbf 100644 --- a/include/nana/gui/widgets/widget.hpp +++ b/include/nana/gui/widgets/widget.hpp @@ -54,9 +54,9 @@ namespace nana window parent() const; - ::std::string caption() const throw(); - ::std::wstring caption_wstring() const throw(); - native_string_type caption_native() const throw(); + ::std::string caption() const noexcept; + ::std::wstring caption_wstring() const noexcept; + native_string_type caption_native() const noexcept; widget& caption(std::string utf8); widget& caption(std::wstring); @@ -130,7 +130,7 @@ namespace nana virtual void _m_complete_creation(); virtual general_events& _m_get_general_events() const = 0; - virtual native_string_type _m_caption() const throw(); + virtual native_string_type _m_caption() const noexcept; virtual void _m_caption(native_string_type&&); virtual nana::cursor _m_cursor() const; virtual void _m_cursor(nana::cursor); diff --git a/include/nana/paint/graphics.hpp b/include/nana/paint/graphics.hpp index 9ce35704..800b88c5 100644 --- a/include/nana/paint/graphics.hpp +++ b/include/nana/paint/graphics.hpp @@ -149,7 +149,7 @@ namespace nana /// Saves images as a windows bitmap file /// @param file_utf8 A UTF-8 string to a filename - void save_as_file(const char* file_utf8) const throw(); + void save_as_file(const char* file_utf8) const noexcept; ::nana::color palette(bool for_text) const; graphics& palette(bool for_text, const ::nana::color&); diff --git a/source/gui/programming_interface.cpp b/source/gui/programming_interface.cpp index 22e22cac..1e1fdddd 100644 --- a/source/gui/programming_interface.cpp +++ b/source/gui/programming_interface.cpp @@ -242,7 +242,7 @@ namespace API } } - ::nana::detail::native_string_type window_caption(window wd) throw() + ::nana::detail::native_string_type window_caption(window wd) noexcept { auto const iwd = reinterpret_cast(wd); internal_scope_guard isg; diff --git a/source/gui/widgets/combox.cpp b/source/gui/widgets/combox.cpp index c9b6311d..812c6d44 100644 --- a/source/gui/widgets/combox.cpp +++ b/source/gui/widgets/combox.cpp @@ -1037,7 +1037,7 @@ namespace nana API::refresh_window(*this); } - auto combox::_m_caption() const throw() -> native_string_type + auto combox::_m_caption() const noexcept -> native_string_type { internal_scope_guard lock; auto editor = _m_impl().editor(); diff --git a/source/gui/widgets/group.cpp b/source/gui/widgets/group.cpp index ab8e9e73..63458f8b 100644 --- a/source/gui/widgets/group.cpp +++ b/source/gui/widgets/group.cpp @@ -239,7 +239,7 @@ namespace nana{ _m_init(); } - auto group::_m_caption() const throw() -> native_string_type + auto group::_m_caption() const noexcept -> native_string_type { return impl_->caption.caption_native(); } diff --git a/source/gui/widgets/label.cpp b/source/gui/widgets/label.cpp index 1d436f68..300d0fcc 100644 --- a/source/gui/widgets/label.cpp +++ b/source/gui/widgets/label.cpp @@ -825,7 +825,7 @@ namespace nana return *this; } - bool label::transparent() const throw() + bool label::transparent() const noexcept { return API::is_transparent_background(*this); } @@ -849,7 +849,7 @@ namespace nana return *this; } - label& label::click_for(window associated_window) throw() + label& label::click_for(window associated_window) noexcept { get_drawer_trigger().impl()->for_associated_wd = associated_window; return *this; diff --git a/source/gui/widgets/spinbox.cpp b/source/gui/widgets/spinbox.cpp index 5bf2b342..5a62b10a 100644 --- a/source/gui/widgets/spinbox.cpp +++ b/source/gui/widgets/spinbox.cpp @@ -764,7 +764,7 @@ namespace nana modifier(to_utf8(prefix), to_utf8(suffix)); } - auto spinbox::_m_caption() const throw() -> native_string_type + auto spinbox::_m_caption() const noexcept -> native_string_type { internal_scope_guard lock; auto editor = get_drawer_trigger().impl()->editor(); diff --git a/source/gui/widgets/tabbar.cpp b/source/gui/widgets/tabbar.cpp index ad614c09..2337f468 100644 --- a/source/gui/widgets/tabbar.cpp +++ b/source/gui/widgets/tabbar.cpp @@ -1533,7 +1533,7 @@ namespace nana delete model_; } - model* driver::get_model() const throw() + model* driver::get_model() const noexcept { return model_; } diff --git a/source/gui/widgets/textbox.cpp b/source/gui/widgets/textbox.cpp index de6e2dd9..96c927f3 100644 --- a/source/gui/widgets/textbox.cpp +++ b/source/gui/widgets/textbox.cpp @@ -785,7 +785,7 @@ namespace drawerbase { } //Override _m_caption for caption() - auto textbox::_m_caption() const throw() -> native_string_type + auto textbox::_m_caption() const noexcept -> native_string_type { internal_scope_guard lock; auto editor = get_drawer_trigger().editor(); diff --git a/source/gui/widgets/widget.cpp b/source/gui/widgets/widget.cpp index 183768ab..bcc239ad 100644 --- a/source/gui/widgets/widget.cpp +++ b/source/gui/widgets/widget.cpp @@ -54,12 +54,12 @@ namespace nana widget& wdg_; }; - std::string widget::caption() const throw() + std::string widget::caption() const noexcept { return to_utf8(_m_caption()); } - std::wstring widget::caption_wstring() const throw() + std::wstring widget::caption_wstring() const noexcept { #if defined(NANA_WINDOWS) return _m_caption(); @@ -68,7 +68,7 @@ namespace nana #endif } - auto widget::caption_native() const throw() -> native_string_type + auto widget::caption_native() const noexcept -> native_string_type { return _m_caption(); } @@ -282,7 +282,7 @@ namespace nana void widget::_m_complete_creation() {} - auto widget::_m_caption() const throw() -> native_string_type + auto widget::_m_caption() const noexcept -> native_string_type { return API::dev::window_caption(handle()); } diff --git a/source/paint/graphics.cpp b/source/paint/graphics.cpp index 62f74016..49857d2e 100644 --- a/source/paint/graphics.cpp +++ b/source/paint/graphics.cpp @@ -934,7 +934,7 @@ namespace paint impl_->size.width = impl_->size.height = 0; } - void graphics::save_as_file(const char* file_utf8) const throw() + void graphics::save_as_file(const char* file_utf8) const noexcept { if(impl_->handle) { From 9d75d15474653fa5fb20d99089c2d759f22d3648 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Wed, 20 Dec 2017 01:28:05 +0800 Subject: [PATCH 4/8] add detection of C++17 folding experssion --- include/nana/c++defines.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/nana/c++defines.hpp b/include/nana/c++defines.hpp index 70db8f8f..98c23dc4 100644 --- a/include/nana/c++defines.hpp +++ b/include/nana/c++defines.hpp @@ -202,6 +202,7 @@ #undef _nana_cxx_constexpr_if #if (defined(_MSC_VER) && (_MSC_VER >= 1912) && defined(_MSVC_LANG) && _MSVC_LANG>= 201703) # define _nana_cxx_constexpr_if +# define _nana_cxx_folding_expression #endif From c66895ead61a4b2ed9bd60c5d0b136686d10a617 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Wed, 20 Dec 2017 11:53:29 +0800 Subject: [PATCH 5/8] apply C++17 folding expression --- include/nana/gui/msgbox.hpp | 6 ++++++ source/gui/msgbox.cpp | 2 ++ 2 files changed, 8 insertions(+) diff --git a/include/nana/gui/msgbox.hpp b/include/nana/gui/msgbox.hpp index 67840f1a..382bb4d8 100644 --- a/include/nana/gui/msgbox.hpp +++ b/include/nana/gui/msgbox.hpp @@ -240,7 +240,11 @@ namespace nana bool show(Args&& ... args) { std::vector contents; +#ifdef _nana_cxx_folding_expression + (contents.emplace_back(&args), ...); +#else _m_fetch_args(contents, std::forward(args)...); +#endif if (contents.empty()) return false; @@ -270,6 +274,7 @@ namespace nana void min_width_entry_field( unsigned pixels ); private: +#ifndef _nana_cxx_folding_expression void _m_fetch_args(std::vector&); template @@ -278,6 +283,7 @@ namespace nana contents.push_back(&content); _m_fetch_args(contents, std::forward(args)...); } +#endif bool _m_open(std::vector&, bool modal); private: diff --git a/source/gui/msgbox.cpp b/source/gui/msgbox.cpp index 75ce6a23..36a7c202 100644 --- a/source/gui/msgbox.cpp +++ b/source/gui/msgbox.cpp @@ -1294,8 +1294,10 @@ namespace nana min_width_entry_field_pixels_ = pixels; } +#ifndef _nana_cxx_folding_expression void inputbox::_m_fetch_args(std::vector&) {} +#endif bool inputbox::_m_open(std::vector& contents, bool modal) { From 4917b18c705c9468a2810528163d88ae535ec82b Mon Sep 17 00:00:00 2001 From: Jinhao Date: Wed, 20 Dec 2017 13:51:32 +0800 Subject: [PATCH 6/8] deprecate std::iterator because of C++17 --- include/nana/c++defines.hpp | 1 + .../gui/widgets/detail/widget_iterator.hpp | 36 +++++++++++++++++++ include/nana/gui/widgets/listbox.hpp | 7 ++-- 3 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 include/nana/gui/widgets/detail/widget_iterator.hpp diff --git a/include/nana/c++defines.hpp b/include/nana/c++defines.hpp index 98c23dc4..fa43923d 100644 --- a/include/nana/c++defines.hpp +++ b/include/nana/c++defines.hpp @@ -203,6 +203,7 @@ #if (defined(_MSC_VER) && (_MSC_VER >= 1912) && defined(_MSVC_LANG) && _MSVC_LANG>= 201703) # define _nana_cxx_constexpr_if # define _nana_cxx_folding_expression +# define _nana_cxx_nested_namespace_definition #endif diff --git a/include/nana/gui/widgets/detail/widget_iterator.hpp b/include/nana/gui/widgets/detail/widget_iterator.hpp new file mode 100644 index 00000000..c78e5d4d --- /dev/null +++ b/include/nana/gui/widgets/detail/widget_iterator.hpp @@ -0,0 +1,36 @@ +/* + * A Widget Iterator Template + * Copyright(C) 2017 Jinhao(cnjinhao@hotmail.com) + * + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * @file: nana/gui/widgets/detail/widget_iterator.hpp + * @description: widget_iterator is the base class provided to simplify definitions of the required types for widget iterators. + * It is provided because of deprecation of std::iterator in C++17 + */ +#ifndef NANA_GUI_WIDGET_ITERATOR_INCLUDED +#define NANA_GUI_WIDGET_ITERATOR_INCLUDED + +#include //provides std::ptrdiff_t + + +namespace nana { + namespace widgets { + namespace detail + { + template + class widget_iterator + { + using iterator_category = Category; + using value_type = T; + using difference_type = std::ptrdiff_t; + using pointer = T * ; + using reference = T & ; + }; + } + } +} + +#endif diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index 71280b7e..0137ff51 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -23,6 +23,7 @@ #include "widget.hpp" #include "detail/inline_widget.hpp" +#include "detail/widget_iterator.hpp" #include #include #include @@ -802,7 +803,8 @@ namespace nana /// operate with absolute positions and contain only the position but montain pointers to parts of the real items /// item_proxy self, it references and iterators are not invalidated by sort() class item_proxy - : public std::iterator + //: public std::iterator //deprecated + : public ::nana::widgets::detail::widget_iterator { public: item_proxy(essence*, const index_pair& = index_pair{npos, npos}); @@ -976,7 +978,8 @@ namespace nana }; class cat_proxy - : public std::iterator < std::input_iterator_tag, cat_proxy > + //: public std::iterator //deprecated + : public ::nana::widgets::detail::widget_iterator { public: using inline_notifier_interface = drawerbase::listbox::inline_notifier_interface; From be836b5b480311df1511659337ec62ef1c4befe6 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sat, 23 Dec 2017 00:10:10 +0800 Subject: [PATCH 7/8] apply folding expression and std::optional --- include/nana/c++defines.hpp | 1 + .../widget_content_measurer_interface.hpp | 8 +++-- include/nana/gui/programming_interface.hpp | 2 +- include/nana/internationalization.hpp | 35 +++++++++++++------ include/nana/optional.hpp | 10 +++++- source/gui/programming_interface.cpp | 2 +- source/gui/widgets/button.cpp | 2 +- source/gui/widgets/combox.cpp | 2 +- source/gui/widgets/label.cpp | 2 +- source/gui/widgets/picture.cpp | 2 +- source/internationalization.cpp | 20 ++++++----- 11 files changed, 58 insertions(+), 28 deletions(-) diff --git a/include/nana/c++defines.hpp b/include/nana/c++defines.hpp index fa43923d..80b8e504 100644 --- a/include/nana/c++defines.hpp +++ b/include/nana/c++defines.hpp @@ -204,6 +204,7 @@ # define _nana_cxx_constexpr_if # define _nana_cxx_folding_expression # define _nana_cxx_nested_namespace_definition +# define _nana_std_optional #endif diff --git a/include/nana/gui/detail/widget_content_measurer_interface.hpp b/include/nana/gui/detail/widget_content_measurer_interface.hpp index 4f175493..22184c34 100644 --- a/include/nana/gui/detail/widget_content_measurer_interface.hpp +++ b/include/nana/gui/detail/widget_content_measurer_interface.hpp @@ -14,7 +14,11 @@ #define NANA_WIDGET_CONTENT_MEASURER_INTERFACE_HEADER_INCLUDED #include -#include +#ifdef _nana_std_optional +# include +#else +# include +#endif #include namespace nana @@ -35,7 +39,7 @@ namespace nana * @param limit_width True if limits the width, false if limits the height. * @return the size of content. */ - virtual optional measure(graph_reference graph, unsigned limit_pixels, bool limit_width) const = 0; + virtual ::std::optional measure(graph_reference graph, unsigned limit_pixels, bool limit_width) const = 0; /// Returns the extension to the size of widget from content extent /** diff --git a/include/nana/gui/programming_interface.hpp b/include/nana/gui/programming_interface.hpp index 45ca629c..db7e2ac2 100644 --- a/include/nana/gui/programming_interface.hpp +++ b/include/nana/gui/programming_interface.hpp @@ -461,7 +461,7 @@ namespace API * @return if optional has a value, the first size indicates the content extent, the second size indicates the size of * widget by the content extent. */ - optional> content_extent(window wd, unsigned limited_px, bool limit_width); + std::optional> content_extent(window wd, unsigned limited_px, bool limit_width); }//end namespace API }//end namespace nana diff --git a/include/nana/internationalization.hpp b/include/nana/internationalization.hpp index 4b3e3918..86c31250 100644 --- a/include/nana/internationalization.hpp +++ b/include/nana/internationalization.hpp @@ -34,7 +34,12 @@ namespace nana ::std::string get(std::string msgid_utf8, Args&&... args) const { std::vector arg_strs; + +#ifdef _nana_cxx_folding_expression + (_m_fetch_args(arg_strs, std::forward(args)),...); +#else _m_fetch_args(arg_strs, std::forward(args)...); +#endif auto msgstr = _m_get(std::move(msgid_utf8)); _m_replace_args(msgstr, &arg_strs); @@ -53,25 +58,28 @@ namespace nana std::string _m_get(std::string&& msgid) const; void _m_replace_args(::std::string& str, std::vector<::std::string> * arg_strs) const; - void _m_fetch_args(std::vector&) const; //Termination of _m_fetch_args +#ifndef _nana_cxx_folding_expression + static void _m_fetch_args(std::vector&); //Termination of _m_fetch_args +#endif - void _m_fetch_args(std::vector& v, const char* arg) const; - void _m_fetch_args(std::vector& v, const std::string& arg) const; - void _m_fetch_args(std::vector& v, std::string& arg) const; - void _m_fetch_args(std::vector& v, std::string&& arg) const; - void _m_fetch_args(std::vector& v, const wchar_t* arg) const; - void _m_fetch_args(std::vector& v, const std::wstring& arg) const; - void _m_fetch_args(std::vector& v, std::wstring& arg) const; - void _m_fetch_args(std::vector& v, std::wstring&& arg) const; + static void _m_fetch_args(std::vector& v, const char* arg); + static void _m_fetch_args(std::vector& v, const std::string& arg); + static void _m_fetch_args(std::vector& v, std::string& arg); + static void _m_fetch_args(std::vector& v, std::string&& arg); + static void _m_fetch_args(std::vector& v, const wchar_t* arg); + static void _m_fetch_args(std::vector& v, const std::wstring& arg); + static void _m_fetch_args(std::vector& v, std::wstring& arg); + static void _m_fetch_args(std::vector& v, std::wstring&& arg); template - void _m_fetch_args(std::vector& v, Arg&& arg) const + static void _m_fetch_args(std::vector& v, Arg&& arg) { std::stringstream ss; ss << arg; v.emplace_back(ss.str()); } +#ifndef _nana_cxx_folding_expression template void _m_fetch_args(std::vector& v, const char* arg, Args&&... args) const { @@ -136,6 +144,7 @@ namespace nana v.emplace_back(ss.str()); _m_fetch_args(v, std::forward(args)...); } +#endif };//end class internationalization class i18n_eval @@ -180,7 +189,11 @@ namespace nana i18n_eval(std::string msgid_utf8, Args&&... args) : msgid_(std::move(msgid_utf8)) { +#ifdef _nana_cxx_folding_expression + (_m_fetch_args(std::forward(args)), ...); +#else _m_fetch_args(std::forward(args)...); +#endif } i18n_eval(const i18n_eval&); @@ -193,6 +206,7 @@ namespace nana std::string operator()() const; private: +#ifndef _nana_cxx_folding_expression void _m_fetch_args(){} //Termination of _m_fetch_args template @@ -201,6 +215,7 @@ namespace nana _m_add_args(std::forward(arg)); _m_fetch_args(std::forward(args)...); } +#endif template void _m_add_args(Arg&& arg) diff --git a/include/nana/optional.hpp b/include/nana/optional.hpp index 49b81d88..17b4189e 100644 --- a/include/nana/optional.hpp +++ b/include/nana/optional.hpp @@ -15,8 +15,11 @@ #ifndef NANA_STD_OPTIONAL_HEADER_INCLUDED #define NANA_STD_OPTIONAL_HEADER_INCLUDED -#include #include + +#ifndef _nana_std_optional +#include + namespace nana { namespace detail @@ -361,4 +364,9 @@ namespace nana }; } +namespace std +{ + using nana::optional; +} +#endif //_nana_std_optional #endif diff --git a/source/gui/programming_interface.cpp b/source/gui/programming_interface.cpp index 1e1fdddd..7aed26a3 100644 --- a/source/gui/programming_interface.cpp +++ b/source/gui/programming_interface.cpp @@ -1450,7 +1450,7 @@ namespace API restrict::wd_manager().set_safe_place(reinterpret_cast(wd), std::move(fn)); } - optional> content_extent(window wd, unsigned limited_px, bool limit_width) + std::optional> content_extent(window wd, unsigned limited_px, bool limit_width) { auto iwd = reinterpret_cast(wd); internal_scope_guard lock; diff --git a/source/gui/widgets/button.cpp b/source/gui/widgets/button.cpp index a01d001b..752f084f 100644 --- a/source/gui/widgets/button.cpp +++ b/source/gui/widgets/button.cpp @@ -27,7 +27,7 @@ namespace nana{ namespace drawerbase : trigger_{ t } {} - optional measure(graph_reference graph, unsigned limit_pixels, bool /*limit_width*/) const override + std::optional measure(graph_reference graph, unsigned limit_pixels, bool /*limit_width*/) const override { //Button doesn't provide a support of vfit and hfit if (limit_pixels) diff --git a/source/gui/widgets/combox.cpp b/source/gui/widgets/combox.cpp index 812c6d44..dcaf5c43 100644 --- a/source/gui/widgets/combox.cpp +++ b/source/gui/widgets/combox.cpp @@ -90,7 +90,7 @@ namespace nana : drw_{ drwimpl } {} - optional measure(graph_reference graph, unsigned limit_pixels, bool /*limit_width*/) const override + std::optional measure(graph_reference graph, unsigned limit_pixels, bool /*limit_width*/) const override { //Combox doesn't provide a support of vfit and hfit if (limit_pixels) diff --git a/source/gui/widgets/label.cpp b/source/gui/widgets/label.cpp index 300d0fcc..bf670c12 100644 --- a/source/gui/widgets/label.cpp +++ b/source/gui/widgets/label.cpp @@ -653,7 +653,7 @@ namespace nana : impl_{ impl } {} - optional measure(graph_reference graph, unsigned limit_pixels, bool limit_width) const override + std::optional measure(graph_reference graph, unsigned limit_pixels, bool limit_width) const override { //Label now doesn't support to measure content with a specified height. if (graph && ((0 == limit_pixels) || limit_width)) diff --git a/source/gui/widgets/picture.cpp b/source/gui/widgets/picture.cpp index 356072b9..cba8a75c 100644 --- a/source/gui/widgets/picture.cpp +++ b/source/gui/widgets/picture.cpp @@ -74,7 +74,7 @@ namespace nana : impl_{impl} {} - optional measure(graph_reference /*graph*/, unsigned limit_pixels, bool /*limit_width*/) const override + std::optional measure(graph_reference /*graph*/, unsigned limit_pixels, bool /*limit_width*/) const override { //Picture doesn't provide a support of vfit and hfit if (!limit_pixels) diff --git a/source/internationalization.cpp b/source/internationalization.cpp index 87c92437..4252d73c 100644 --- a/source/internationalization.cpp +++ b/source/internationalization.cpp @@ -414,45 +414,47 @@ namespace nana } } - void internationalization::_m_fetch_args(std::vector&) const +#ifndef _nana_cxx_folding_expression + void internationalization::_m_fetch_args(std::vector&) {} +#endif - void internationalization::_m_fetch_args(std::vector& v, const char* arg) const + void internationalization::_m_fetch_args(std::vector& v, const char* arg) { v.emplace_back(arg); } - void internationalization::_m_fetch_args(std::vector& v, const std::string& arg) const + void internationalization::_m_fetch_args(std::vector& v, const std::string& arg) { v.emplace_back(arg); } - void internationalization::_m_fetch_args(std::vector& v, std::string& arg) const + void internationalization::_m_fetch_args(std::vector& v, std::string& arg) { v.emplace_back(arg); } - void internationalization::_m_fetch_args(std::vector& v, std::string&& arg) const + void internationalization::_m_fetch_args(std::vector& v, std::string&& arg) { v.emplace_back(std::move(arg)); } - void internationalization::_m_fetch_args(std::vector& v, const wchar_t* arg) const + void internationalization::_m_fetch_args(std::vector& v, const wchar_t* arg) { v.emplace_back(to_utf8(arg)); } - void internationalization::_m_fetch_args(std::vector& v, const std::wstring& arg) const + void internationalization::_m_fetch_args(std::vector& v, const std::wstring& arg) { v.emplace_back(to_utf8(arg)); } - void internationalization::_m_fetch_args(std::vector& v, std::wstring& arg) const + void internationalization::_m_fetch_args(std::vector& v, std::wstring& arg) { v.emplace_back(to_utf8(arg)); } - void internationalization::_m_fetch_args(std::vector& v, std::wstring&& arg) const + void internationalization::_m_fetch_args(std::vector& v, std::wstring&& arg) { v.emplace_back(to_utf8(arg)); } From 9c1f348a80728d307f7bd797b3ea7f22507d352c Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Mon, 29 Jan 2018 01:35:09 +0100 Subject: [PATCH 8/8] Fix travis test/demos with gcc 4.9 and boost 1.54 --- include/nana/filesystem/filesystem.hpp | 31 ++++++++++++++++++++++ include/nana/filesystem/filesystem_ext.hpp | 11 ++++++++ 2 files changed, 42 insertions(+) diff --git a/include/nana/filesystem/filesystem.hpp b/include/nana/filesystem/filesystem.hpp index 067586f5..b6c358b7 100644 --- a/include/nana/filesystem/filesystem.hpp +++ b/include/nana/filesystem/filesystem.hpp @@ -55,6 +55,37 @@ #define NANA_USING_BOOST_FILESYSTEM 1 # include # include +// dont include generic_u8string +// http://www.boost.org/doc/libs/1_66_0/boost/filesystem/path.hpp +// enable directory_iterator C++11 range-base for +// http://www.boost.org/doc/libs/1_66_0/boost/filesystem/operations.hpp +// but travis come with an oooold version of boost +// NOT enable directory_iterator C++11 range-base for +// http://www.boost.org/doc/libs/1_54_0/boost/filesystem/operations.hpp +namespace boost +{ + namespace filesystem + { + + // enable directory_iterator C++11 range-base for statement use --------------------// + + // begin() and end() are only used by a range-based for statement in the context of + // auto - thus the top-level const is stripped - so returning const is harmless and + // emphasizes begin() is just a pass through. + inline + const directory_iterator& begin(const directory_iterator& iter) BOOST_NOEXCEPT + { + return iter; + } + inline + directory_iterator end(const directory_iterator&) BOOST_NOEXCEPT + { + return directory_iterator(); + } + + } // namespace filesystem +} + // add boost::filesystem into std::experimental::filesystem namespace std { diff --git a/include/nana/filesystem/filesystem_ext.hpp b/include/nana/filesystem/filesystem_ext.hpp index 2c28acad..3458a198 100644 --- a/include/nana/filesystem/filesystem_ext.hpp +++ b/include/nana/filesystem/filesystem_ext.hpp @@ -16,6 +16,7 @@ #define NANA_FILESYSTEM_EXT_HPP #include +#include namespace nana { @@ -34,6 +35,16 @@ namespace filesystem_ext std::experimental::filesystem::path path_user(); ///< extention ? + /// workaround Boost not having path.generic_u8string() - a good point for http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0251r0.pdf +inline std::string generic_u8string(const std::experimental::filesystem::path& p) +{ +#if NANA_USING_BOOST_FILESYSTEM + return nana::to_utf8(p.generic_wstring()); +#else + return p.generic_u8string(); +#endif +} + inline bool is_directory(const std::experimental::filesystem::directory_entry& dir) noexcept { return is_directory(dir.status());