Merge branch 'develop-c++17' into develop

This commit is contained in:
Jinhao 2018-06-04 02:29:55 +08:00
commit a9f23e2503
35 changed files with 270 additions and 86 deletions

View File

@ -36,9 +36,9 @@
* - STD_TO_STRING_NOT_SUPPORTED (MinGW with GCC < 4.8) * - STD_TO_STRING_NOT_SUPPORTED (MinGW with GCC < 4.8)
* - STD_FILESYSTEM_NOT_SUPPORTED (GCC < 5.3) .... * - STD_FILESYSTEM_NOT_SUPPORTED (GCC < 5.3) ....
* - CXX_NO_INLINE_NAMESPACE (Visual C++ < 2015) * - CXX_NO_INLINE_NAMESPACE (Visual C++ < 2015)
* - _enable_std_make_unique (__cpluscplus < 201402) * - _nana_std_make_unique (__cpluscplus < 201402)
* - _enable_std_put_time (GCC < 5) * - _nana_std_put_time (GCC < 5)
* - _enable_std_clamp (Visual C++ < 2017) * - _nana_std_clamp (Visual C++ < 2017)
*/ */
#ifndef NANA_CXX_DEFINES_INCLUDED #ifndef NANA_CXX_DEFINES_INCLUDED
@ -145,7 +145,7 @@
# if ((__GNUC__ < 5) ) # if ((__GNUC__ < 5) )
# define _enable_std_put_time # define _nana_std_put_time
# endif # endif
# if ((__GNUC__ > 5) || ((__GNUC__ == 5) && (__GNUC_MINOR__ >= 3 ) ) ) # if ((__GNUC__ > 5) || ((__GNUC__ == 5) && (__GNUC_MINOR__ >= 3 ) ) )
@ -189,20 +189,28 @@
//Detects the feature std::make_unique //Detects the feature std::make_unique
//std::make_unique has been provided by Visual C++ 2013 and later //std::make_unique has been provided by Visual C++ 2013 and later
#undef _enable_std_make_unique #undef _nana_std_make_unique
#if (defined(__clang__) && (__cplusplus < 201305L || (__cplusplus == 201305L && (__clang_major__ * 100 + __clang_minor__ < 304 )))) \ #if (defined(__clang__) && (__cplusplus < 201305L || (__cplusplus == 201305L && (__clang_major__ * 100 + __clang_minor__ < 304 )))) \
|| ((!defined(__clang__)) && defined(__GNUC__) && __cplusplus < 201300L) || ((!defined(__clang__)) && defined(__GNUC__) && __cplusplus < 201300L)
# define _enable_std_make_unique # define _nana_std_make_unique
#endif #endif
//Detects the feature std::clamp //Detects the feature std::clamp
//Visual C++ 2017 with /std:c++latest provides the std::clamp //Visual C++ 2017 with /std:c++latest provides the std::clamp
#undef _enable_std_clamp #undef _nana_std_clamp
#if (defined(_MSC_VER) && ((!defined(_MSVC_LANG)) || _MSVC_LANG < 201403L)) \ #if (defined(_MSC_VER) && ((!defined(_MSVC_LANG)) || _MSVC_LANG < 201403L)) \
|| (defined(__clang__) && (__cplusplus < 201406L)) \ || (defined(__clang__) && (__cplusplus < 201406L)) \
|| (defined(__GNUC__) && (!defined(__clang__)) && (__cplusplus < 201703)) || (defined(__GNUC__) && (!defined(__clang__)) && (__cplusplus < 201703))
# define _enable_std_clamp # define _nana_std_clamp
#endif
#undef _nana_std_optional
#if ((defined(_MSC_VER) && (_MSC_VER >= 1912) && defined(_MSVC_LANG) && _MSVC_LANG>= 201703)) || \
(defined(__clang__) && (__clang_major__ * 100 + __clang_minor__ >= 400)) || \
(!defined(__clang__) && defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 701)
# define _nana_std_optional
#endif #endif

View File

@ -134,10 +134,24 @@ namespace nana
template<typename Function> template<typename Function>
event_handle connect_front(Function && fn) event_handle connect_front(Function && fn)
{ {
#ifdef __cpp_if_constexpr
if constexpr(std::is_invocable_v<Function, arg_reference>)
{
return _m_emplace(new docker{ this, fn, false }, true);
}
else if constexpr(std::is_invocable_v<Function>)
{
return _m_emplace(new docker{ this, [fn](arg_reference) {
fn();
}, false }, true);
}
#else
using prototype = typename std::remove_reference<Function>::type; using prototype = typename std::remove_reference<Function>::type;
return _m_emplace(new docker(this, factory<prototype, std::is_bind_expression<prototype>::value>::build(std::forward<Function>(fn)), false), true); return _m_emplace(new docker(this, factory<prototype, std::is_bind_expression<prototype>::value>::build(std::forward<Function>(fn)), false), true);
#endif
} }
#ifndef __cpp_if_constexpr
/// It will not get called if stop_propagation() was called. /// It will not get called if stop_propagation() was called.
event_handle connect(void (*fn)(arg_reference)) event_handle connect(void (*fn)(arg_reference))
{ {
@ -145,13 +159,27 @@ namespace nana
fn(arg); fn(arg);
}); });
} }
#endif
/// It will not get called if stop_propagation() was called, because it is set at the end of the chain.. /// It will not get called if stop_propagation() was called, because it is set at the end of the chain..
template<typename Function> template<typename Function>
event_handle connect(Function && fn) event_handle connect(Function && fn)
{ {
#ifdef __cpp_if_constexpr
if constexpr(std::is_invocable_v<Function, arg_reference>)
{
return _m_emplace(new docker{ this, fn, false }, false);
}
else if constexpr(std::is_invocable_v<Function>)
{
return _m_emplace(new docker{ this, [fn](arg_reference){
fn();
}, false }, false);
}
#else
using prototype = typename std::remove_reference<Function>::type; using prototype = typename std::remove_reference<Function>::type;
return _m_emplace(new docker(this, factory<prototype, std::is_bind_expression<prototype>::value>::build(std::forward<Function>(fn)), false), false); return _m_emplace(new docker(this, factory<prototype, std::is_bind_expression<prototype>::value>::build(std::forward<Function>(fn)), false), false);
#endif
} }
/// It will not get called if stop_propagation() was called. /// It will not get called if stop_propagation() was called.
@ -165,9 +193,21 @@ namespace nana
template<typename Function> template<typename Function>
event_handle connect_unignorable(Function && fn, bool in_front = false) event_handle connect_unignorable(Function && fn, bool in_front = false)
{ {
#ifdef __cpp_if_constexpr
if constexpr(std::is_invocable_v<Function, arg_reference>)
{
return _m_emplace(new docker{ this, fn, true }, in_front);
}
else if constexpr(std::is_invocable_v<Function>)
{
return _m_emplace(new docker{ this, [fn](arg_reference) {
fn();
}, true }, in_front);
}
#else
using prototype = typename std::remove_reference<Function>::type; using prototype = typename std::remove_reference<Function>::type;
return _m_emplace(new docker(this, factory<prototype, std::is_bind_expression<prototype>::value>::build(std::forward<Function>(fn)), true), in_front); return _m_emplace(new docker(this, factory<prototype, std::is_bind_expression<prototype>::value>::build(std::forward<Function>(fn)), true), in_front);
#endif
} }
void emit(arg_reference& arg, window window_handle) void emit(arg_reference& arg, window window_handle)
@ -210,6 +250,8 @@ namespace nana
} }
} }
private: private:
#ifndef __cpp_if_constexpr
template<typename Fn, bool IsBind> template<typename Fn, bool IsBind>
struct factory struct factory
{ {
@ -385,6 +427,7 @@ namespace nana
}; };
} }
}; };
#endif
}; };
struct arg_mouse struct arg_mouse

View File

@ -35,7 +35,7 @@ namespace nana
* @param limit_width True if limits the width, false if limits the height. * @param limit_width True if limits the width, false if limits the height.
* @return the size of content. * @return the size of content.
*/ */
virtual optional<size> measure(graph_reference graph, unsigned limit_pixels, bool limit_width) const = 0; virtual ::std::optional<size> measure(graph_reference graph, unsigned limit_pixels, bool limit_width) const = 0;
/// Returns the extension to the size of widget from content extent /// Returns the extension to the size of widget from content extent
/** /**

View File

@ -240,7 +240,11 @@ namespace nana
bool show(Args&& ... args) bool show(Args&& ... args)
{ {
std::vector<abstract_content*> contents; std::vector<abstract_content*> contents;
#ifdef __cpp_fold_expressions
(contents.emplace_back(&args), ...);
#else
_m_fetch_args(contents, std::forward<Args>(args)...); _m_fetch_args(contents, std::forward<Args>(args)...);
#endif
if (contents.empty()) if (contents.empty())
return false; return false;
@ -270,6 +274,7 @@ namespace nana
void min_width_entry_field( unsigned pixels ); void min_width_entry_field( unsigned pixels );
private: private:
#ifndef __cpp_fold_expressions
void _m_fetch_args(std::vector<abstract_content*>&); void _m_fetch_args(std::vector<abstract_content*>&);
template<typename ...Args> template<typename ...Args>
@ -278,6 +283,7 @@ namespace nana
contents.push_back(&content); contents.push_back(&content);
_m_fetch_args(contents, std::forward<Args>(args)...); _m_fetch_args(contents, std::forward<Args>(args)...);
} }
#endif
bool _m_open(std::vector<abstract_content*>&, bool modal); bool _m_open(std::vector<abstract_content*>&, bool modal);
private: private:

View File

@ -89,7 +89,7 @@ namespace API
void set_measurer(window, ::nana::dev::widget_content_measurer_interface*); void set_measurer(window, ::nana::dev::widget_content_measurer_interface*);
void attach_drawer(widget&, drawer_trigger&); 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); void window_caption(window, ::nana::detail::native_string_type);
window create_window(window, bool nested, const rectangle&, const appearance&, widget* attached); window create_window(window, bool nested, const rectangle&, const appearance&, widget* attached);
@ -255,6 +255,19 @@ namespace API
if (nullptr == general_evt) if (nullptr == general_evt)
throw std::invalid_argument("API::events(): bad parameter window handle, no events object or invalid window handle."); throw std::invalid_argument("API::events(): bad parameter window handle, no events object or invalid window handle.");
#ifdef __cpp_if_constexpr
if constexpr(std::is_same_v<event_type, ::nana::general_events>)
{
return *general_evt;
}
else
{
auto * widget_evt = dynamic_cast<event_type*>(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) if (std::is_same<::nana::general_events, event_type>::value)
return *static_cast<event_type*>(general_evt); return *static_cast<event_type*>(general_evt);
@ -262,6 +275,7 @@ namespace API
if (nullptr == widget_evt) if (nullptr == widget_evt)
throw std::invalid_argument("API::events(): bad template parameter Widget, the widget type and window handle do not match."); throw std::invalid_argument("API::events(): bad template parameter Widget, the widget type and window handle do not match.");
return *widget_evt; return *widget_evt;
#endif
} }
template<typename EventArg, typename std::enable_if<std::is_base_of< ::nana::event_arg, EventArg>::value>::type* = nullptr> template<typename EventArg, typename std::enable_if<std::is_base_of< ::nana::event_arg, EventArg>::value>::type* = nullptr>
@ -288,6 +302,19 @@ namespace API
if (nullptr == wdg_colors) if (nullptr == wdg_colors)
throw std::invalid_argument("API::scheme(): bad parameter window handle, no events object or invalid window handle."); throw std::invalid_argument("API::scheme(): bad parameter window handle, no events object or invalid window handle.");
#ifdef __cpp_if_constexpr
if constexpr(std::is_same<::nana::widget_geometrics, scheme_type>::value)
{
return *static_cast<scheme_type*>(wdg_colors);
}
else
{
auto * comp_wdg_colors = dynamic_cast<scheme_type*>(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) if (std::is_same<::nana::widget_geometrics, scheme_type>::value)
return *static_cast<scheme_type*>(wdg_colors); return *static_cast<scheme_type*>(wdg_colors);
@ -295,6 +322,7 @@ namespace API
if (nullptr == comp_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."); throw std::invalid_argument("API::scheme(): bad template parameter Widget, the widget type and window handle do not match.");
return *comp_wdg_colors; return *comp_wdg_colors;
#endif
} }
point window_position(window); point window_position(window);
@ -312,7 +340,7 @@ namespace API
size window_outline_size(window); size window_outline_size(window);
void window_outline_size(window, const size&); void window_outline_size(window, const size&);
nana::optional<rectangle> window_rectangle(window); ::std::optional<rectangle> window_rectangle(window);
bool get_window_rectangle(window, rectangle&); bool get_window_rectangle(window, rectangle&);
bool track_window_size(window, const size&, bool true_for_max); ///< Sets the minimum or maximum tracking size of a window. bool track_window_size(window, const size&, bool true_for_max); ///< Sets the minimum or maximum tracking size of a window.
void window_enabled(window, bool); void window_enabled(window, bool);
@ -434,7 +462,7 @@ namespace API
bool ignore_mouse_focus(window, bool ignore); ///< Enables/disables the mouse focus, it returns the previous state bool ignore_mouse_focus(window, bool ignore); ///< Enables/disables the mouse focus, it returns the previous state
bool ignore_mouse_focus(window); ///< Determines whether the mouse focus is enabled bool ignore_mouse_focus(window); ///< Determines whether the mouse focus is enabled
void at_safe_place(window, std::function<void()>); void at_safe_place(window, ::std::function<void()>);
/// Returns a widget content extent size /// Returns a widget content extent size
/** /**
@ -445,7 +473,7 @@ namespace API
* @return if optional has a value, the first size indicates the content extent, the second size indicates the size of * @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. * widget by the content extent.
*/ */
optional<std::pair<::nana::size, ::nana::size>> content_extent(window wd, unsigned limited_px, bool limit_width); ::std::optional<std::pair<::nana::size, ::nana::size>> content_extent(window wd, unsigned limited_px, bool limit_width);
unsigned screen_dpi(bool x_requested); unsigned screen_dpi(bool x_requested);
}//end namespace API }//end namespace API

View File

@ -223,7 +223,7 @@ namespace nana
const drawerbase::combox::drawer_impl& _m_impl() const; const drawerbase::combox::drawer_impl& _m_impl() const;
private: private:
//Overrides widget's virtual functions //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_caption(native_string_type&&) override;
nana::any * _m_anyobj(std::size_t pos, bool alloc_if_empty) const override; nana::any * _m_anyobj(std::size_t pos, bool alloc_if_empty) const override;
}; };

View File

@ -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 <cstddef> //provides std::ptrdiff_t
namespace nana {
namespace widgets {
namespace detail
{
template<typename Category, typename T>
class widget_iterator
{
using iterator_category = Category;
using value_type = T;
using difference_type = std::ptrdiff_t;
using pointer = T * ;
using reference = T & ;
};
}
}
}
#endif

View File

@ -83,7 +83,7 @@ namespace nana{
void _m_add_child(const char* field, widget*); void _m_add_child(const char* field, widget*);
void _m_init(); void _m_init();
void _m_complete_creation() override; 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; void _m_caption(native_string_type&&) override;
private: private:
std::unique_ptr<implement> impl_; std::unique_ptr<implement> impl_;

View File

@ -62,12 +62,12 @@ namespace nana
label(window parent, const char* text, bool visible = true) :label(parent, std::string(text),visible) {}; label(window parent, const char* text, bool visible = true) :label(parent, std::string(text),visible) {};
label(window, const rectangle& = {}, bool visible = true); label(window, const rectangle& = {}, bool visible = true);
label& transparent(bool); ///< Switchs the label widget to the transparent background mode. 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& format(bool); ///< Switches the format mode of the widget.
label& add_format_listener(std::function<void(command, const std::string&)>); label& add_format_listener(std::function<void(command, const std::string&)>);
/// as same as the HTML "for" attribute of a label /// 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 /// 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 /// "corrected" size that changes lines to fit the text into the specified width

View File

@ -23,6 +23,7 @@
#include "widget.hpp" #include "widget.hpp"
#include "detail/inline_widget.hpp" #include "detail/inline_widget.hpp"
#include "detail/widget_iterator.hpp"
#include <nana/pat/abstract_factory.hpp> #include <nana/pat/abstract_factory.hpp>
#include <nana/concepts.hpp> #include <nana/concepts.hpp>
#include <nana/key_type.hpp> #include <nana/key_type.hpp>
@ -808,7 +809,8 @@ namespace nana
/// operate with absolute positions and contain only the position but montain pointers to parts of the real items /// 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() /// item_proxy self, it references and iterators are not invalidated by sort()
class item_proxy class item_proxy
: public std::iterator<std::input_iterator_tag, item_proxy> //: public std::iterator<std::input_iterator_tag, item_proxy> //deprecated
: public ::nana::widgets::detail::widget_iterator<std::input_iterator_tag, item_proxy>
{ {
public: public:
item_proxy(essence*, const index_pair& = index_pair{npos, npos}); item_proxy(essence*, const index_pair& = index_pair{npos, npos});
@ -982,7 +984,8 @@ namespace nana
}; };
class cat_proxy class cat_proxy
: public std::iterator < std::input_iterator_tag, cat_proxy > //: public std::iterator<std::input_iterator_tag, cat_proxy> //deprecated
: public ::nana::widgets::detail::widget_iterator<std::input_iterator_tag, cat_proxy>
{ {
public: public:
using inline_notifier_interface = drawerbase::listbox::inline_notifier_interface; using inline_notifier_interface = drawerbase::listbox::inline_notifier_interface;

View File

@ -116,7 +116,7 @@ namespace nana
void modifier(std::string prefix_utf8, std::string suffix_utf8); void modifier(std::string prefix_utf8, std::string suffix_utf8);
void modifier(const std::wstring & prefix, const std::wstring& suffix); void modifier(const std::wstring & prefix, const std::wstring& suffix);
private: private:
native_string_type _m_caption() const throw(); native_string_type _m_caption() const noexcept;
void _m_caption(native_string_type&&); void _m_caption(native_string_type&&);
}; //end class spinbox }; //end class spinbox
}//end namespace nana }//end namespace nana

View File

@ -383,7 +383,7 @@ namespace nana
driver(); driver();
~driver(); ~driver();
model* get_model() const throw(); model* get_model() const noexcept;
private: private:
//Overrides drawer_trigger's method //Overrides drawer_trigger's method
void attached(widget_reference, graph_reference) override; void attached(widget_reference, graph_reference) override;

View File

@ -276,7 +276,7 @@ namespace nana
std::size_t text_line_count() const noexcept; std::size_t text_line_count() const noexcept;
protected: protected:
//Overrides widget's virtual functions //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_caption(native_string_type&&) override;
void _m_typeface(const paint::font&) override; void _m_typeface(const paint::font&) override;
std::shared_ptr<scroll_operation_interface> _m_scroll_operation() override; std::shared_ptr<scroll_operation_interface> _m_scroll_operation() override;

View File

@ -54,9 +54,9 @@ namespace nana
window parent() const; window parent() const;
::std::string caption() const throw(); ::std::string caption() const noexcept;
::std::wstring caption_wstring() const throw(); ::std::wstring caption_wstring() const noexcept;
native_string_type caption_native() const throw(); native_string_type caption_native() const noexcept;
widget& caption(std::string utf8); widget& caption(std::string utf8);
widget& caption(std::wstring); widget& caption(std::wstring);
@ -132,7 +132,7 @@ namespace nana
virtual void _m_complete_creation(); virtual void _m_complete_creation();
virtual general_events& _m_get_general_events() const = 0; 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 void _m_caption(native_string_type&&);
virtual nana::cursor _m_cursor() const; virtual nana::cursor _m_cursor() const;
virtual void _m_cursor(nana::cursor); virtual void _m_cursor(nana::cursor);

View File

@ -34,7 +34,12 @@ namespace nana
::std::string get(std::string msgid_utf8, Args&&... args) const ::std::string get(std::string msgid_utf8, Args&&... args) const
{ {
std::vector<std::string> arg_strs; std::vector<std::string> arg_strs;
#ifdef __cpp_fold_expressions
(_m_fetch_args(arg_strs, std::forward<Args>(args)),...);
#else
_m_fetch_args(arg_strs, std::forward<Args>(args)...); _m_fetch_args(arg_strs, std::forward<Args>(args)...);
#endif
auto msgstr = _m_get(std::move(msgid_utf8)); auto msgstr = _m_get(std::move(msgid_utf8));
_m_replace_args(msgstr, &arg_strs); _m_replace_args(msgstr, &arg_strs);
@ -53,25 +58,28 @@ namespace nana
std::string _m_get(std::string&& msgid) const; std::string _m_get(std::string&& msgid) const;
void _m_replace_args(::std::string& str, std::vector<::std::string> * arg_strs) const; void _m_replace_args(::std::string& str, std::vector<::std::string> * arg_strs) const;
void _m_fetch_args(std::vector<std::string>&) const; //Termination of _m_fetch_args #ifndef __cpp_fold_expressions
static void _m_fetch_args(std::vector<std::string>&); //Termination of _m_fetch_args
#endif
void _m_fetch_args(std::vector<std::string>& v, const char* arg) const; static void _m_fetch_args(std::vector<std::string>& v, const char* arg);
void _m_fetch_args(std::vector<std::string>& v, const std::string& arg) const; static void _m_fetch_args(std::vector<std::string>& v, const std::string& arg);
void _m_fetch_args(std::vector<std::string>& v, std::string& arg) const; static void _m_fetch_args(std::vector<std::string>& v, std::string& arg);
void _m_fetch_args(std::vector<std::string>& v, std::string&& arg) const; static void _m_fetch_args(std::vector<std::string>& v, std::string&& arg);
void _m_fetch_args(std::vector<std::string>& v, const wchar_t* arg) const; static void _m_fetch_args(std::vector<std::string>& v, const wchar_t* arg);
void _m_fetch_args(std::vector<std::string>& v, const std::wstring& arg) const; static void _m_fetch_args(std::vector<std::string>& v, const std::wstring& arg);
void _m_fetch_args(std::vector<std::string>& v, std::wstring& arg) const; static void _m_fetch_args(std::vector<std::string>& v, std::wstring& arg);
void _m_fetch_args(std::vector<std::string>& v, std::wstring&& arg) const; static void _m_fetch_args(std::vector<std::string>& v, std::wstring&& arg);
template<typename Arg> template<typename Arg>
void _m_fetch_args(std::vector<std::string>& v, Arg&& arg) const static void _m_fetch_args(std::vector<std::string>& v, Arg&& arg)
{ {
std::stringstream ss; std::stringstream ss;
ss << arg; ss << arg;
v.emplace_back(ss.str()); v.emplace_back(ss.str());
} }
#ifndef __cpp_fold_expressions
template<typename ...Args> template<typename ...Args>
void _m_fetch_args(std::vector<std::string>& v, const char* arg, Args&&... args) const void _m_fetch_args(std::vector<std::string>& v, const char* arg, Args&&... args) const
{ {
@ -136,6 +144,7 @@ namespace nana
v.emplace_back(ss.str()); v.emplace_back(ss.str());
_m_fetch_args(v, std::forward<Args>(args)...); _m_fetch_args(v, std::forward<Args>(args)...);
} }
#endif
};//end class internationalization };//end class internationalization
class i18n_eval class i18n_eval
@ -180,7 +189,11 @@ namespace nana
i18n_eval(std::string msgid_utf8, Args&&... args) i18n_eval(std::string msgid_utf8, Args&&... args)
: msgid_(std::move(msgid_utf8)) : msgid_(std::move(msgid_utf8))
{ {
#ifdef __cpp_fold_expressions
(_m_fetch_args(std::forward<Args>(args)), ...);
#else
_m_fetch_args(std::forward<Args>(args)...); _m_fetch_args(std::forward<Args>(args)...);
#endif
} }
i18n_eval(const i18n_eval&); i18n_eval(const i18n_eval&);
@ -193,6 +206,7 @@ namespace nana
std::string operator()() const; std::string operator()() const;
private: private:
#ifndef __cpp_fold_expressions
void _m_fetch_args(){} //Termination of _m_fetch_args void _m_fetch_args(){} //Termination of _m_fetch_args
template<typename Arg, typename ...Args> template<typename Arg, typename ...Args>
@ -201,6 +215,7 @@ namespace nana
_m_add_args(std::forward<Arg>(arg)); _m_add_args(std::forward<Arg>(arg));
_m_fetch_args(std::forward<Args>(args)...); _m_fetch_args(std::forward<Args>(args)...);
} }
#endif
template<typename Arg> template<typename Arg>
void _m_add_args(Arg&& arg) void _m_add_args(Arg&& arg)

View File

@ -15,8 +15,13 @@
#ifndef NANA_STD_OPTIONAL_HEADER_INCLUDED #ifndef NANA_STD_OPTIONAL_HEADER_INCLUDED
#define NANA_STD_OPTIONAL_HEADER_INCLUDED #define NANA_STD_OPTIONAL_HEADER_INCLUDED
#include <stdexcept>
#include <nana/c++defines.hpp> #include <nana/c++defines.hpp>
#ifdef _nana_std_optional
#include <optional>
#else
#include <stdexcept>
namespace nana namespace nana
{ {
namespace detail namespace detail
@ -361,4 +366,10 @@ namespace nana
}; };
} }
namespace std
{
using nana::optional;
}
#endif //_nana_std_optional
#endif #endif

View File

@ -156,7 +156,7 @@ namespace nana
/// Saves images as a windows bitmap file /// Saves images as a windows bitmap file
/// @param file_utf8 A UTF-8 string to a filename /// @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; ::nana::color palette(bool for_text) const;
graphics& palette(bool for_text, const ::nana::color&); graphics& palette(bool for_text, const ::nana::color&);

View File

@ -86,7 +86,7 @@ namespace std
} }
#endif #endif
#ifdef _enable_std_make_unique #ifdef _nana_std_make_unique
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3656.htm // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3656.htm
#include <cstddef> #include <cstddef>
@ -124,9 +124,9 @@ namespace std {
typename _Unique_if<T>::_Known_bound typename _Unique_if<T>::_Known_bound
make_unique(Args&&...) = delete; make_unique(Args&&...) = delete;
} }
#endif //_enable_std_make_unique #endif //_nana_std_make_unique
#ifdef _enable_std_put_time #ifdef _nana_std_put_time
#include <ctime> #include <ctime>
#include <string> #include <string>
namespace std namespace std
@ -144,9 +144,9 @@ namespace std
//template<> //template<>
//std::wstring put_time<wchar_t, std::wstring>(const std::tm* tmb, const wchar_t* fmt); //std::wstring put_time<wchar_t, std::wstring>(const std::tm* tmb, const wchar_t* fmt);
} }
#endif // _enable_std_put_time #endif // _nana_std_put_time
#if defined(_enable_std_clamp) #if defined(_nana_std_clamp)
namespace std namespace std
{ {
//<algorithm> since C++17 //<algorithm> since C++17

View File

@ -80,7 +80,7 @@
#pragma message ( SHOW_VALUE(USE_github_com_meganz_mingw_std_threads) ) #pragma message ( SHOW_VALUE(USE_github_com_meganz_mingw_std_threads) )
#pragma message ( SHOW_VALUE(NANA_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ) ) #pragma message ( SHOW_VALUE(NANA_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ) )
#pragma message ( SHOW_VALUE(STD_THREAD_NOT_SUPPORTED) ) #pragma message ( SHOW_VALUE(STD_THREAD_NOT_SUPPORTED) )
#pragma message ( SHOW_VALUE(_enable_std_put_time) ) #pragma message ( SHOW_VALUE(_nana_std_put_time) )
#pragma message ( SHOW_VALUE(STD_MAKE_UNIQUE_NOT_SUPPORTED) ) #pragma message ( SHOW_VALUE(STD_MAKE_UNIQUE_NOT_SUPPORTED) )
#pragma message ( SHOW_VALUE(STD_FILESYSTEM_NOT_SUPPORTED) ) #pragma message ( SHOW_VALUE(STD_FILESYSTEM_NOT_SUPPORTED) )

View File

@ -16,7 +16,7 @@
#include <sstream> #include <sstream>
#include <nana/config.hpp> #include <nana/config.hpp>
#ifdef _enable_std_put_time #ifdef _nana_std_put_time
#include <nana/stdc++.hpp> #include <nana/stdc++.hpp>
#else #else
#include <iomanip> #include <iomanip>

View File

@ -1294,8 +1294,10 @@ namespace nana
min_width_entry_field_pixels_ = pixels; min_width_entry_field_pixels_ = pixels;
} }
#ifndef _nana_cxx_folding_expression
void inputbox::_m_fetch_args(std::vector<abstract_content*>&) void inputbox::_m_fetch_args(std::vector<abstract_content*>&)
{} {}
#endif
bool inputbox::_m_open(std::vector<abstract_content*>& contents, bool modal) bool inputbox::_m_open(std::vector<abstract_content*>& contents, bool modal)
{ {

View File

@ -260,7 +260,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<basic_window*>(wd); auto const iwd = reinterpret_cast<basic_window*>(wd);
internal_scope_guard isg; internal_scope_guard isg;
@ -838,7 +838,7 @@ namespace API
} }
} }
nana::optional<rectangle> window_rectangle(window wd) std::optional<rectangle> window_rectangle(window wd)
{ {
auto iwd = reinterpret_cast<basic_window*>(wd); auto iwd = reinterpret_cast<basic_window*>(wd);
internal_scope_guard lock; internal_scope_guard lock;
@ -1476,7 +1476,7 @@ namespace API
restrict::wd_manager().set_safe_place(reinterpret_cast<basic_window*>(wd), std::move(fn)); restrict::wd_manager().set_safe_place(reinterpret_cast<basic_window*>(wd), std::move(fn));
} }
optional<std::pair<size, size>> content_extent(window wd, unsigned limited_px, bool limit_width) std::optional<std::pair<size, size>> content_extent(window wd, unsigned limited_px, bool limit_width)
{ {
auto iwd = reinterpret_cast<basic_window*>(wd); auto iwd = reinterpret_cast<basic_window*>(wd);
internal_scope_guard lock; internal_scope_guard lock;

View File

@ -27,7 +27,7 @@ namespace nana{ namespace drawerbase
: trigger_{ t } : trigger_{ t }
{} {}
optional<size> measure(graph_reference graph, unsigned limit_pixels, bool /*limit_width*/) const override std::optional<size> measure(graph_reference graph, unsigned limit_pixels, bool /*limit_width*/) const override
{ {
//Button doesn't provide a support of vfit and hfit //Button doesn't provide a support of vfit and hfit
if (limit_pixels) if (limit_pixels)

View File

@ -90,7 +90,7 @@ namespace nana
: drw_{ drwimpl } : drw_{ drwimpl }
{} {}
optional<size> measure(graph_reference graph, unsigned limit_pixels, bool /*limit_width*/) const override std::optional<size> measure(graph_reference graph, unsigned limit_pixels, bool /*limit_width*/) const override
{ {
//Combox doesn't provide a support of vfit and hfit //Combox doesn't provide a support of vfit and hfit
if (limit_pixels) if (limit_pixels)
@ -1037,7 +1037,7 @@ namespace nana
API::refresh_window(*this); 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; internal_scope_guard lock;
auto editor = _m_impl().editor(); auto editor = _m_impl().editor();

View File

@ -271,7 +271,7 @@ namespace nana{
_m_init(); _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(); return impl_->caption.caption_native();
} }

View File

@ -653,7 +653,7 @@ namespace nana
: impl_{ impl } : impl_{ impl }
{} {}
optional<size> measure(graph_reference graph, unsigned limit_pixels, bool limit_width) const override std::optional<size> measure(graph_reference graph, unsigned limit_pixels, bool limit_width) const override
{ {
//Label now doesn't support to measure content with a specified height. //Label now doesn't support to measure content with a specified height.
if (graph && ((0 == limit_pixels) || limit_width)) if (graph && ((0 == limit_pixels) || limit_width))
@ -825,7 +825,7 @@ namespace nana
return *this; return *this;
} }
bool label::transparent() const throw() bool label::transparent() const noexcept
{ {
return API::is_transparent_background(*this); return API::is_transparent_background(*this);
} }
@ -849,7 +849,7 @@ namespace nana
return *this; 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; get_drawer_trigger().impl()->for_associated_wd = associated_window;
return *this; return *this;

View File

@ -74,7 +74,7 @@ namespace nana
: impl_{impl} : impl_{impl}
{} {}
optional<size> measure(graph_reference /*graph*/, unsigned limit_pixels, bool /*limit_width*/) const override std::optional<size> measure(graph_reference /*graph*/, unsigned limit_pixels, bool /*limit_width*/) const override
{ {
//Picture doesn't provide a support of vfit and hfit //Picture doesn't provide a support of vfit and hfit
if (!limit_pixels) if (!limit_pixels)

View File

@ -82,10 +82,39 @@ namespace nana
bool check_value(const std::string& str) const override bool check_value(const std::string& str) const override
{ {
#ifdef __cpp_if_constexpr
auto i = str.c_str();
if ('+' == *i || '-' == *i)
++i;
if constexpr(std::is_same<T, int>::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()) if (str.empty())
return true; return true;
auto size = str.size(); auto const size = str.size();
std::size_t pos = 0; std::size_t pos = 0;
if (str[0] == '+' || str[0] == '-') if (str[0] == '+' || str[0] == '-')
pos = 1; pos = 1;
@ -115,6 +144,7 @@ namespace nana
return false; return false;
} }
} }
#endif
return true; return true;
} }
@ -744,7 +774,7 @@ namespace nana
modifier(to_utf8(prefix), to_utf8(suffix)); 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; internal_scope_guard lock;
auto editor = get_drawer_trigger().impl()->editor(); auto editor = get_drawer_trigger().impl()->editor();

View File

@ -1533,7 +1533,7 @@ namespace nana
delete model_; delete model_;
} }
model* driver::get_model() const throw() model* driver::get_model() const noexcept
{ {
return model_; return model_;
} }

View File

@ -785,7 +785,7 @@ namespace drawerbase {
} }
//Override _m_caption for caption() //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; internal_scope_guard lock;
auto editor = get_drawer_trigger().editor(); auto editor = get_drawer_trigger().editor();

View File

@ -54,12 +54,12 @@ namespace nana
widget& wdg_; widget& wdg_;
}; };
std::string widget::caption() const throw() std::string widget::caption() const noexcept
{ {
return to_utf8(_m_caption()); return to_utf8(_m_caption());
} }
std::wstring widget::caption_wstring() const throw() std::wstring widget::caption_wstring() const noexcept
{ {
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
return _m_caption(); return _m_caption();
@ -68,7 +68,7 @@ namespace nana
#endif #endif
} }
auto widget::caption_native() const throw() -> native_string_type auto widget::caption_native() const noexcept -> native_string_type
{ {
return _m_caption(); return _m_caption();
} }
@ -287,7 +287,7 @@ namespace nana
void widget::_m_complete_creation() 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()); return API::dev::window_caption(handle());
} }

View File

@ -414,45 +414,47 @@ namespace nana
} }
} }
void internationalization::_m_fetch_args(std::vector<std::string>&) const #ifndef _nana_cxx_folding_expression
void internationalization::_m_fetch_args(std::vector<std::string>&)
{} {}
#endif
void internationalization::_m_fetch_args(std::vector<std::string>& v, const char* arg) const void internationalization::_m_fetch_args(std::vector<std::string>& v, const char* arg)
{ {
v.emplace_back(arg); v.emplace_back(arg);
} }
void internationalization::_m_fetch_args(std::vector<std::string>& v, const std::string& arg) const void internationalization::_m_fetch_args(std::vector<std::string>& v, const std::string& arg)
{ {
v.emplace_back(arg); v.emplace_back(arg);
} }
void internationalization::_m_fetch_args(std::vector<std::string>& v, std::string& arg) const void internationalization::_m_fetch_args(std::vector<std::string>& v, std::string& arg)
{ {
v.emplace_back(arg); v.emplace_back(arg);
} }
void internationalization::_m_fetch_args(std::vector<std::string>& v, std::string&& arg) const void internationalization::_m_fetch_args(std::vector<std::string>& v, std::string&& arg)
{ {
v.emplace_back(std::move(arg)); v.emplace_back(std::move(arg));
} }
void internationalization::_m_fetch_args(std::vector<std::string>& v, const wchar_t* arg) const void internationalization::_m_fetch_args(std::vector<std::string>& v, const wchar_t* arg)
{ {
v.emplace_back(to_utf8(arg)); v.emplace_back(to_utf8(arg));
} }
void internationalization::_m_fetch_args(std::vector<std::string>& v, const std::wstring& arg) const void internationalization::_m_fetch_args(std::vector<std::string>& v, const std::wstring& arg)
{ {
v.emplace_back(to_utf8(arg)); v.emplace_back(to_utf8(arg));
} }
void internationalization::_m_fetch_args(std::vector<std::string>& v, std::wstring& arg) const void internationalization::_m_fetch_args(std::vector<std::string>& v, std::wstring& arg)
{ {
v.emplace_back(to_utf8(arg)); v.emplace_back(to_utf8(arg));
} }
void internationalization::_m_fetch_args(std::vector<std::string>& v, std::wstring&& arg) const void internationalization::_m_fetch_args(std::vector<std::string>& v, std::wstring&& arg)
{ {
v.emplace_back(to_utf8(arg)); v.emplace_back(to_utf8(arg));
} }

View File

@ -937,7 +937,7 @@ namespace paint
impl_->size.width = impl_->size.height = 0; 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) if(impl_->handle)
{ {

View File

@ -426,7 +426,7 @@ namespace std
} }
#endif #endif
#ifdef _enable_std_put_time #ifdef _nana_std_put_time
#include <cwchar> #include <cwchar>
namespace std namespace std
{ {