aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2019-03-21 22:22:02 +0800
committercrupest <crupest@outlook.com>2019-03-21 22:22:02 +0800
commit962dc18ee4827b464764ec3708be3d00a9143971 (patch)
tree3eea13894a14a26f2e2de07d3d6bc7789d409864 /src
parentafa2a079562d810e5ef611071b21a3568da9dfca (diff)
downloadcru-962dc18ee4827b464764ec3708be3d00a9143971.tar.gz
cru-962dc18ee4827b464764ec3708be3d00a9143971.tar.bz2
cru-962dc18ee4827b464764ec3708be3d00a9143971.zip
...
Diffstat (limited to 'src')
-rw-r--r--src/base.hpp8
-rw-r--r--src/cru_debug.cpp2
-rw-r--r--src/cru_debug.hpp4
-rw-r--r--src/ui/content_control.cpp32
-rw-r--r--src/ui/content_control.hpp31
-rw-r--r--src/ui/control.cpp110
-rw-r--r--src/ui/control.hpp136
-rw-r--r--src/ui/controls/flex_layout.hpp4
-rw-r--r--src/ui/controls/text_block.hpp2
-rw-r--r--src/ui/layout_control.cpp52
-rw-r--r--src/ui/layout_control.hpp33
-rw-r--r--src/ui/no_child_control.cpp5
-rw-r--r--src/ui/no_child_control.hpp26
-rw-r--r--src/ui/window.cpp86
-rw-r--r--src/ui/window.hpp9
-rw-r--r--src/util/format.hpp42
16 files changed, 303 insertions, 279 deletions
diff --git a/src/base.hpp b/src/base.hpp
index a62a745b..2c511c4b 100644
--- a/src/base.hpp
+++ b/src/base.hpp
@@ -7,9 +7,6 @@
#include <string_view>
namespace cru {
-template <typename T>
-struct type_tag {};
-
// typedefs
using String = std::wstring;
using MultiByteString = std::string;
@@ -38,9 +35,4 @@ struct Interface {
[[noreturn]] inline void UnreachableCode() {
throw std::logic_error("Unreachable code.");
}
-
-inline void Require(const bool condition,
- const MultiByteStringView& error_message) {
- if (!condition) throw std::invalid_argument(error_message.data());
-}
} // namespace cru
diff --git a/src/cru_debug.cpp b/src/cru_debug.cpp
index b9226132..331d2bce 100644
--- a/src/cru_debug.cpp
+++ b/src/cru_debug.cpp
@@ -3,7 +3,9 @@
#include "system_headers.hpp"
namespace cru::debug {
+#ifdef CRU_DEBUG
void DebugMessage(const StringView& message) {
::OutputDebugStringW(message.data());
}
+#endif
} // namespace cru::debug
diff --git a/src/cru_debug.hpp b/src/cru_debug.hpp
index 9c22a24f..58431d56 100644
--- a/src/cru_debug.hpp
+++ b/src/cru_debug.hpp
@@ -7,7 +7,11 @@
#include "util/format.hpp"
namespace cru::debug {
+#ifdef CRU_DEBUG
void DebugMessage(const StringView& message);
+#else
+inline void DebugMessage(const StringView& message) {}
+#endif
#ifdef CRU_DEBUG
inline void DebugTime(const std::function<void()>& action,
diff --git a/src/ui/content_control.cpp b/src/ui/content_control.cpp
new file mode 100644
index 00000000..960867b2
--- /dev/null
+++ b/src/ui/content_control.cpp
@@ -0,0 +1,32 @@
+#include "content_control.hpp"
+
+#include "window.hpp"
+
+namespace cru::ui {
+ContentControl::ContentControl()
+ : child_vector_{nullptr}, child_(child_vector_[0]) {}
+
+ContentControl::~ContentControl() { delete child_; }
+
+void ContentControl::SetChild(Control* child) {
+ if (dynamic_cast<Window*>(child))
+ throw std::invalid_argument("Can't add a window as child.");
+
+ if (child == child_) return;
+
+ const auto window = GetWindow();
+ const auto old_child = child_;
+ child_ = child;
+ if (old_child) {
+ old_child->_SetParent(nullptr);
+ old_child->_SetDescendantWindow(nullptr);
+ }
+ if (child) {
+ child->_SetParent(this);
+ child->_SetDescendantWindow(window);
+ }
+ OnChildChanged(old_child, child);
+}
+
+void ContentControl::OnChildChanged(Control* old_child, Control* new_child) {}
+} // namespace cru::ui
diff --git a/src/ui/content_control.hpp b/src/ui/content_control.hpp
new file mode 100644
index 00000000..88e7f60f
--- /dev/null
+++ b/src/ui/content_control.hpp
@@ -0,0 +1,31 @@
+#pragma once
+#include "pre.hpp"
+
+#include "control.hpp"
+
+namespace cru::ui {
+class ContentControl : public Control {
+ protected:
+ ContentControl();
+
+ public:
+ ContentControl(const ContentControl& other) = delete;
+ ContentControl(ContentControl&& other) = delete;
+ ContentControl& operator=(const ContentControl& other) = delete;
+ ContentControl& operator=(ContentControl&& other) = delete;
+ ~ContentControl() override;
+
+ const std::vector<Control*>& GetChildren() const override final {
+ return child_vector_;
+ }
+ Control* GetChild() const { return child_; }
+ void SetChild(Control* child);
+
+ protected:
+ virtual void OnChildChanged(Control* old_child, Control* new_child);
+
+ private:
+ std::vector<Control*> child_vector_;
+ Control*& child_;
+};
+} // namespace cru::ui
diff --git a/src/ui/control.cpp b/src/ui/control.cpp
index 98986d3c..e19754dc 100644
--- a/src/ui/control.cpp
+++ b/src/ui/control.cpp
@@ -35,14 +35,14 @@ void Control::_SetDescendantWindow(Window* window) {
void Control::TraverseDescendants(
const std::function<void(Control*)>& predicate) {
- TraverseDescendantsInternal(this, predicate);
+ _TraverseDescendants(this, predicate);
}
-void Control::TraverseDescendantsInternal(
+void Control::_TraverseDescendants(
Control* control, const std::function<void(Control*)>& predicate) {
predicate(control);
for (auto c : control->GetChildren())
- TraverseDescendantsInternal(c, predicate);
+ _TraverseDescendants(c, predicate);
}
bool Control::RequestFocus() {
auto window = GetWindow();
@@ -76,108 +76,4 @@ void Control::OnDetachToWindow(Window* window) {}
void Control::OnMouseClickBegin(MouseButton button) {}
void Control::OnMouseClickEnd(MouseButton button) {}
-
-const std::vector<Control*> NoChildControl::empty_control_vector{};
-
-ContentControl::ContentControl()
- : child_vector_{nullptr}, child_(child_vector_[0]) {}
-
-ContentControl::~ContentControl() { delete child_; }
-
-void ContentControl::SetChild(Control* child) {
- if (child == child_) return;
-
- const auto window = GetWindow();
- const auto old_child = child_;
- child_ = child;
- if (old_child) {
- old_child->_SetParent(nullptr);
- old_child->_SetDescendantWindow(nullptr);
- }
- if (child) {
- child->_SetParent(this);
- child->_SetDescendantWindow(window);
- }
- OnChildChanged(old_child, child);
-}
-
-void ContentControl::OnChildChanged(Control* old_child, Control* new_child) {}
-
-void ControlAddChildCheck(Control* control) {
- if (control->GetParent() != nullptr)
- throw std::invalid_argument("The control already has a parent.");
-
- if (dynamic_cast<Window*>(control))
- throw std::invalid_argument("Can't add a window as child.");
-}
-
-Layout::~Layout() {
- for (const auto child : children_) delete child;
-}
-
-void Layout::AddChild(Control* control, const int position) {
- ControlAddChildCheck(control);
-
- if (position < 0 || static_cast<decltype(children_.size())>(position) >
- this->children_.size())
- throw std::invalid_argument("The position is out of range.");
-
- children_.insert(this->children_.cbegin() + position, control);
-
- control->_SetParent(this);
- control->_SetDescendantWindow(GetWindow());
-
- OnAddChild(control, position);
-}
-
-void Layout::RemoveChild(const int position) {
- if (position < 0 || static_cast<decltype(this->children_.size())>(position) >=
- this->children_.size())
- throw std::invalid_argument("The position is out of range.");
-
- const auto i = children_.cbegin() + position;
- const auto child = *i;
-
- children_.erase(i);
-
- child->_SetParent(nullptr);
- child->_SetDescendantWindow(nullptr);
-
- OnRemoveChild(child, position);
-}
-
-void Layout::OnAddChild(Control* child, int position) {}
-
-void Layout::OnRemoveChild(Control* child, int position) {}
-
-std::list<Control*> GetAncestorList(Control* control) {
- std::list<Control*> l;
- while (control != nullptr) {
- l.push_front(control);
- control = control->GetParent();
- }
- return l;
-}
-
-Control* FindLowestCommonAncestor(Control* left, Control* right) {
- if (left == nullptr || right == nullptr) return nullptr;
-
- auto&& left_list = GetAncestorList(left);
- auto&& right_list = GetAncestorList(right);
-
- // the root is different
- if (left_list.front() != right_list.front()) return nullptr;
-
- // find the last same control or the last control (one is ancestor of the
- // other)
- auto left_i = left_list.cbegin();
- auto right_i = right_list.cbegin();
- while (true) {
- if (left_i == left_list.cend()) return *(--left_i);
- if (right_i == right_list.cend()) return *(--right_i);
- if (*left_i != *right_i) return *(--left_i);
- ++left_i;
- ++right_i;
- }
-}
} // namespace cru::ui
diff --git a/src/ui/control.hpp b/src/ui/control.hpp
index 9ff407b0..8454e981 100644
--- a/src/ui/control.hpp
+++ b/src/ui/control.hpp
@@ -48,7 +48,7 @@ class Control : public Object {
void _SetDescendantWindow(Window* window);
private:
- static void TraverseDescendantsInternal(
+ static void _TraverseDescendants(
Control* control, const std::function<void(Control*)>& predicate);
public:
@@ -110,138 +110,4 @@ class Control : public Object {
Cursor::Ptr cursor_{};
};
-
-class NoChildControl : public Control {
- private:
- static const std::vector<Control*> empty_control_vector;
-
- protected:
- NoChildControl() = default;
-
- public:
- NoChildControl(const NoChildControl& other) = delete;
- NoChildControl(NoChildControl&& other) = delete;
- NoChildControl& operator=(const NoChildControl& other) = delete;
- NoChildControl& operator=(NoChildControl&& other) = delete;
- ~NoChildControl() override = default;
-
- protected:
- const std::vector<Control*>& GetChildren() const override final {
- return empty_control_vector;
- }
-};
-
-class ContentControl : public Control {
- protected:
- ContentControl();
-
- public:
- ContentControl(const ContentControl& other) = delete;
- ContentControl(ContentControl&& other) = delete;
- ContentControl& operator=(const ContentControl& other) = delete;
- ContentControl& operator=(ContentControl&& other) = delete;
- ~ContentControl() override;
-
- const std::vector<Control*>& GetChildren() const override final {
- return child_vector_;
- }
- Control* GetChild() const { return child_; }
- void SetChild(Control* child);
-
- protected:
- virtual void OnChildChanged(Control* old_child, Control* new_child);
-
- private:
- std::vector<Control*> child_vector_;
- Control*& child_;
-};
-
-class Layout : public Control {
- protected:
- Layout() = default;
-
- public:
- Layout(const Layout& other) = delete;
- Layout(Layout&& other) = delete;
- Layout& operator=(const Layout& other) = delete;
- Layout& operator=(Layout&& other) = delete;
- ~Layout() override;
-
- const std::vector<Control*>& GetChildren() const override final {
- return children_;
- }
-
- void AddChild(Control* control, int position);
-
- void RemoveChild(int position);
-
- protected:
- virtual void OnAddChild(Control* child, int position);
- virtual void OnRemoveChild(Control* child, int position);
-
- private:
- std::vector<Control*> children_;
-};
-
-//*************** region: event dispatcher helper ***************
-
-// Dispatch the event.
-//
-// This will raise routed event of the control and its parent and parent's
-// parent ... (until "last_receiver" if it's not nullptr) with appropriate args.
-//
-// First tunnel from top to bottom possibly stopped by "handled" flag in
-// EventArgs. Second bubble from bottom to top possibly stopped by "handled"
-// flag in EventArgs. Last direct to each control.
-//
-// Args is of type "EventArgs". The first init argument is "sender", which is
-// automatically bound to each receiving control. The second init argument is
-// "original_sender", which is unchanged. And "args" will be perfectly forwarded
-// as the rest arguments.
-template <typename EventArgs, typename... Args>
-void DispatchEvent(Control* const original_sender,
- events::RoutedEvent<EventArgs> Control::*event_ptr,
- Control* const last_receiver, Args&&... args) {
- std::list<Control*> receive_list;
-
- auto parent = original_sender;
- while (parent != last_receiver) {
- receive_list.push_back(parent);
- parent = parent->GetParent();
- }
-
- auto handled = false;
-
- // tunnel
- for (auto i = receive_list.crbegin(); i != receive_list.crend(); ++i) {
- EventArgs event_args(*i, original_sender, std::forward<Args>(args)...);
- (*i->*event_ptr).tunnel.Raise(event_args);
- if (event_args.IsHandled()) {
- handled = true;
- break;
- }
- }
-
- // bubble
- if (!handled) {
- for (auto i : receive_list) {
- EventArgs event_args(i, original_sender, std::forward<Args>(args)...);
- (i->*event_ptr).bubble.Raise(event_args);
- if (event_args.IsHandled()) break;
- }
- }
-
- // direct
- for (auto i : receive_list) {
- EventArgs event_args(i, original_sender, std::forward<Args>(args)...);
- (i->*event_ptr).direct.Raise(event_args);
- }
-}
-
-//*************** region: tree helper ***************
-
-// Find the lowest common ancestor.
-// Return nullptr if "left" and "right" are not in the same tree.
-Control* FindLowestCommonAncestor(Control* left, Control* right);
-
} // namespace cru::ui
diff --git a/src/ui/controls/flex_layout.hpp b/src/ui/controls/flex_layout.hpp
index 682ed8dc..2ab3e259 100644
--- a/src/ui/controls/flex_layout.hpp
+++ b/src/ui/controls/flex_layout.hpp
@@ -1,7 +1,7 @@
#pragma once
#include "pre.hpp"
-#include "ui/control.hpp"
+#include "ui/layout_control.hpp"
namespace cru::ui::render {
class FlexLayoutRenderObject;
@@ -9,7 +9,7 @@ class FlexLayoutRenderObject;
namespace cru::ui::controls {
-class FlexLayout : public Layout {
+class FlexLayout : public LayoutControl {
public:
static constexpr auto control_type = L"FlexLayout";
diff --git a/src/ui/controls/text_block.hpp b/src/ui/controls/text_block.hpp
index c345c5ab..4c443020 100644
--- a/src/ui/controls/text_block.hpp
+++ b/src/ui/controls/text_block.hpp
@@ -1,7 +1,7 @@
#pragma once
#include "pre.hpp"
-#include "ui/control.hpp"
+#include "ui/no_child_control.hpp"
namespace cru::ui::render {
class TextRenderObject;
diff --git a/src/ui/layout_control.cpp b/src/ui/layout_control.cpp
new file mode 100644
index 00000000..d2b430dd
--- /dev/null
+++ b/src/ui/layout_control.cpp
@@ -0,0 +1,52 @@
+#include "layout_control.hpp"
+
+#include "window.hpp"
+
+namespace cru::ui {
+void ControlAddChildCheck(Control* control) {
+ if (control->GetParent() != nullptr)
+ throw std::invalid_argument("The control already has a parent.");
+
+ if (dynamic_cast<Window*>(control))
+ throw std::invalid_argument("Can't add a window as child.");
+}
+
+LayoutControl::~LayoutControl() {
+ for (const auto child : children_) delete child;
+}
+
+void LayoutControl::AddChild(Control* control, const int position) {
+ ControlAddChildCheck(control);
+
+ if (position < 0 || static_cast<decltype(children_.size())>(position) >
+ this->children_.size())
+ throw std::invalid_argument("The position is out of range.");
+
+ children_.insert(this->children_.cbegin() + position, control);
+
+ control->_SetParent(this);
+ control->_SetDescendantWindow(GetWindow());
+
+ OnAddChild(control, position);
+}
+
+void LayoutControl::RemoveChild(const int position) {
+ if (position < 0 || static_cast<decltype(this->children_.size())>(position) >=
+ this->children_.size())
+ throw std::invalid_argument("The position is out of range.");
+
+ const auto i = children_.cbegin() + position;
+ const auto child = *i;
+
+ children_.erase(i);
+
+ child->_SetParent(nullptr);
+ child->_SetDescendantWindow(nullptr);
+
+ OnRemoveChild(child, position);
+}
+
+void LayoutControl::OnAddChild(Control* child, int position) {}
+
+void LayoutControl::OnRemoveChild(Control* child, int position) {}
+} // namespace cru::ui
diff --git a/src/ui/layout_control.hpp b/src/ui/layout_control.hpp
new file mode 100644
index 00000000..53f53186
--- /dev/null
+++ b/src/ui/layout_control.hpp
@@ -0,0 +1,33 @@
+#pragma once
+#include "pre.hpp"
+
+#include "control.hpp"
+
+namespace cru::ui {
+class LayoutControl : public Control {
+ protected:
+ LayoutControl() = default;
+
+ public:
+ LayoutControl(const LayoutControl& other) = delete;
+ LayoutControl(LayoutControl&& other) = delete;
+ LayoutControl& operator=(const LayoutControl& other) = delete;
+ LayoutControl& operator=(LayoutControl&& other) = delete;
+ ~LayoutControl() override;
+
+ const std::vector<Control*>& GetChildren() const override final {
+ return children_;
+ }
+
+ void AddChild(Control* control, int position);
+
+ void RemoveChild(int position);
+
+ protected:
+ virtual void OnAddChild(Control* child, int position);
+ virtual void OnRemoveChild(Control* child, int position);
+
+ private:
+ std::vector<Control*> children_;
+};
+} // namespace cru::ui
diff --git a/src/ui/no_child_control.cpp b/src/ui/no_child_control.cpp
new file mode 100644
index 00000000..e6bbe813
--- /dev/null
+++ b/src/ui/no_child_control.cpp
@@ -0,0 +1,5 @@
+#include "no_child_control.hpp"
+
+namespace cru::ui {
+const std::vector<Control*> NoChildControl::empty_control_vector{};
+}
diff --git a/src/ui/no_child_control.hpp b/src/ui/no_child_control.hpp
new file mode 100644
index 00000000..26b5546f
--- /dev/null
+++ b/src/ui/no_child_control.hpp
@@ -0,0 +1,26 @@
+#pragma once
+#include "pre.hpp"
+
+#include "control.hpp"
+
+namespace cru::ui {
+class NoChildControl : public Control {
+ private:
+ static const std::vector<Control*> empty_control_vector;
+
+ protected:
+ NoChildControl() = default;
+
+ public:
+ NoChildControl(const NoChildControl& other) = delete;
+ NoChildControl(NoChildControl&& other) = delete;
+ NoChildControl& operator=(const NoChildControl& other) = delete;
+ NoChildControl& operator=(NoChildControl&& other) = delete;
+ ~NoChildControl() override = default;
+
+ protected:
+ const std::vector<Control*>& GetChildren() const override final {
+ return empty_control_vector;
+ }
+};
+} // namespace cru::ui
diff --git a/src/ui/window.cpp b/src/ui/window.cpp
index f92811a7..b976ca6a 100644
--- a/src/ui/window.cpp
+++ b/src/ui/window.cpp
@@ -7,6 +7,92 @@
#include "render/window_render_object.hpp"
namespace cru::ui {
+namespace {
+// Dispatch the event.
+//
+// This will raise routed event of the control and its parent and parent's
+// parent ... (until "last_receiver" if it's not nullptr) with appropriate args.
+//
+// First tunnel from top to bottom possibly stopped by "handled" flag in
+// EventArgs. Second bubble from bottom to top possibly stopped by "handled"
+// flag in EventArgs. Last direct to each control.
+//
+// Args is of type "EventArgs". The first init argument is "sender", which is
+// automatically bound to each receiving control. The second init argument is
+// "original_sender", which is unchanged. And "args" will be perfectly forwarded
+// as the rest arguments.
+template <typename EventArgs, typename... Args>
+void DispatchEvent(Control* const original_sender,
+ events::RoutedEvent<EventArgs> Control::*event_ptr,
+ Control* const last_receiver, Args&&... args) {
+ std::list<Control*> receive_list;
+
+ auto parent = original_sender;
+ while (parent != last_receiver) {
+ receive_list.push_back(parent);
+ parent = parent->GetParent();
+ }
+
+ auto handled = false;
+
+ // tunnel
+ for (auto i = receive_list.crbegin(); i != receive_list.crend(); ++i) {
+ EventArgs event_args(*i, original_sender, std::forward<Args>(args)...);
+ (*i->*event_ptr).tunnel.Raise(event_args);
+ if (event_args.IsHandled()) {
+ handled = true;
+ break;
+ }
+ }
+
+ // bubble
+ if (!handled) {
+ for (auto i : receive_list) {
+ EventArgs event_args(i, original_sender, std::forward<Args>(args)...);
+ (i->*event_ptr).bubble.Raise(event_args);
+ if (event_args.IsHandled()) break;
+ }
+ }
+
+ // direct
+ for (auto i : receive_list) {
+ EventArgs event_args(i, original_sender, std::forward<Args>(args)...);
+ (i->*event_ptr).direct.Raise(event_args);
+ }
+}
+
+std::list<Control*> GetAncestorList(Control* control) {
+ std::list<Control*> l;
+ while (control != nullptr) {
+ l.push_front(control);
+ control = control->GetParent();
+ }
+ return l;
+}
+
+Control* FindLowestCommonAncestor(Control* left, Control* right) {
+ if (left == nullptr || right == nullptr) return nullptr;
+
+ auto&& left_list = GetAncestorList(left);
+ auto&& right_list = GetAncestorList(right);
+
+ // the root is different
+ if (left_list.front() != right_list.front()) return nullptr;
+
+ // find the last same control or the last control (one is ancestor of the
+ // other)
+ auto left_i = left_list.cbegin();
+ auto right_i = right_list.cbegin();
+ while (true) {
+ if (left_i == left_list.cend()) return *(--left_i);
+ if (right_i == right_list.cend()) return *(--right_i);
+ if (*left_i != *right_i) return *(--left_i);
+ ++left_i;
+ ++right_i;
+ }
+}
+} // namespace
+
LRESULT __stdcall GeneralWndProc(HWND hWnd, UINT Msg, WPARAM wParam,
LPARAM lParam) {
auto window = WindowManager::GetInstance()->FromHandle(hWnd);
diff --git a/src/ui/window.hpp b/src/ui/window.hpp
index 7a28c257..3e0422b1 100644
--- a/src/ui/window.hpp
+++ b/src/ui/window.hpp
@@ -5,7 +5,7 @@
#include <memory>
#include "system_headers.hpp"
-#include "control.hpp"
+#include "content_control.hpp"
#include "events/ui_event.hpp"
#include "window_class.hpp"
@@ -230,13 +230,6 @@ class Window final : public ContentControl {
bool window_focus_ = false;
Control* focus_control_ = this; // "focus_control_" can't be nullptr
-
Control* mouse_capture_control_ = nullptr;
-
- bool is_layout_invalid_ = false;
-
-#ifdef CRU_DEBUG_LAYOUT
- bool debug_layout_ = false;
-#endif
};
} // namespace cru::ui
diff --git a/src/util/format.hpp b/src/util/format.hpp
index 874c5b43..7c1cee05 100644
--- a/src/util/format.hpp
+++ b/src/util/format.hpp
@@ -5,26 +5,29 @@
namespace cru::util {
namespace details {
-constexpr StringView PlaceHolder(type_tag<String>) { return StringView(L"{}"); }
+template <typename T>
+struct TypeTag {};
-constexpr MultiByteStringView PlaceHolder(type_tag<MultiByteString>) {
+constexpr StringView PlaceHolder(TypeTag<String>) { return StringView(L"{}"); }
+
+constexpr MultiByteStringView PlaceHolder(TypeTag<MultiByteString>) {
return MultiByteStringView("{}");
}
template <typename TString>
void FormatInternal(TString& string) {
- const auto find_result = string.find(PlaceHolder(type_tag<TString>{}));
+ const auto find_result = string.find(PlaceHolder(TypeTag<TString>{}));
if (find_result != TString::npos)
throw std::invalid_argument("There is more placeholders than args.");
}
template <typename TString, typename T, typename... TRest>
void FormatInternal(TString& string, const T& arg, const TRest&... args) {
- const auto find_result = string.find(PlaceHolder(type_tag<TString>{}));
+ const auto find_result = string.find(PlaceHolder(TypeTag<TString>{}));
if (find_result == TString::npos)
throw std::invalid_argument("There is less placeholders than args.");
- string.replace(find_result, 2, FormatToString(arg, type_tag<TString>{}));
+ string.replace(find_result, 2, FormatToString(arg, TypeTag<TString>{}));
FormatInternal<TString>(string, args...);
}
} // namespace details
@@ -43,13 +46,13 @@ MultiByteString Format(const MultiByteStringView& format, const T&... args) {
return result;
}
-#define CRU_FORMAT_NUMBER(type) \
- inline String FormatToString(const type number, type_tag<String>) { \
- return std::to_wstring(number); \
- } \
- inline MultiByteString FormatToString(const type number, \
- type_tag<MultiByteString>) { \
- return std::to_string(number); \
+#define CRU_FORMAT_NUMBER(type) \
+ inline String FormatToString(const type number, details::TypeTag<String>) { \
+ return std::to_wstring(number); \
+ } \
+ inline MultiByteString FormatToString(const type number, \
+ details::TypeTag<MultiByteString>) { \
+ return std::to_string(number); \
}
CRU_FORMAT_NUMBER(int)
@@ -65,30 +68,33 @@ CRU_FORMAT_NUMBER(double)
#undef CRU_FORMAT_NUMBER
-inline StringView FormatToString(const String& string, type_tag<String>) {
+inline StringView FormatToString(const String& string,
+ details::TypeTag<String>) {
return string;
}
inline MultiByteString FormatToString(const MultiByteString& string,
- type_tag<MultiByteString>) {
+ details::TypeTag<MultiByteString>) {
return string;
}
-inline StringView FormatToString(const StringView& string, type_tag<String>) {
+inline StringView FormatToString(const StringView& string,
+ details::TypeTag<String>) {
return string;
}
inline MultiByteStringView FormatToString(const MultiByteStringView& string,
- type_tag<MultiByteString>) {
+ details::TypeTag<MultiByteString>) {
return string;
}
-inline StringView FormatToString(const wchar_t* string, type_tag<String>) {
+inline StringView FormatToString(const wchar_t* string,
+ details::TypeTag<String>) {
return StringView(string);
}
inline MultiByteStringView FormatToString(const char* string,
- type_tag<MultiByteString>) {
+ details::TypeTag<MultiByteString>) {
return MultiByteString(string);
}
} // namespace cru::util