apply constexpr if

This commit is contained in:
Jinhao 2017-12-18 22:13:03 +08:00
parent 1e551f4e55
commit 486e75f3ae
3 changed files with 106 additions and 5 deletions

View File

@ -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<typename Function>
event_handle connect_front(Function && fn)
{
{
#ifdef _nana_cxx_constexpr_if
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;
return _m_emplace(new docker(this, factory<prototype, std::is_bind_expression<prototype>::value>::build(std::forward<Function>(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<typename Function>
event_handle connect(Function && fn)
{
#ifdef _nana_cxx_constexpr_if
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;
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.
@ -164,10 +192,22 @@ namespace nana
/// It will get called because it is unignorable.
template<typename Function>
event_handle connect_unignorable(Function && fn, bool in_front = false)
{
{
#ifdef _nana_cxx_constexpr_if
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;
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)
@ -210,6 +250,8 @@ namespace nana
}
}
private:
#ifndef _nana_cxx_constexpr_if
template<typename Fn, bool IsBind>
struct factory
{
@ -385,6 +427,7 @@ namespace nana
};
}
};
#endif
};
struct arg_mouse

View File

@ -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<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)
return *static_cast<event_type*>(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<typename EventArg, typename std::enable_if<std::is_base_of< ::nana::event_arg, EventArg>::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<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)
return *static_cast<scheme_type*>(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);

View File

@ -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<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())
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;
}