summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/build.yaml4
-rw-r--r--indra/llmath/tests/v3dmath_test.cpp13
-rw-r--r--indra/llui/llemojihelper.cpp11
-rw-r--r--indra/llui/llemojihelper.h7
-rw-r--r--indra/llui/llscrolllistctrl.cpp87
-rw-r--r--indra/llui/lltexteditor.cpp8
-rw-r--r--indra/llui/lltexteditor.h1
-rw-r--r--indra/newview/llfloaterimsessiontab.cpp42
-rw-r--r--indra/newview/llfloaterimsessiontab.h5
-rw-r--r--indra/newview/llinventorybridge.cpp26
-rw-r--r--indra/newview/llinventorygallery.cpp24
-rw-r--r--indra/newview/llinventorygallerymenu.cpp35
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml16
-rw-r--r--indra/test/lltut.h47
14 files changed, 229 insertions, 97 deletions
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index a287f29b95..fda6545e83 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -47,7 +47,7 @@ jobs:
continue-on-error: ${{ matrix.experimental }}
strategy:
matrix:
- runner: [windows-large, macos-12-xl]
+ runner: [windows-large, macos-14-xlarge]
configuration: ${{ fromJSON(needs.setup.outputs.configurations) }}
experimental: [false]
include:
@@ -73,7 +73,7 @@ jobs:
# autobuild-package.xml.
AUTOBUILD_VCS_INFO: "true"
AUTOBUILD_VSVER: "170"
- DEVELOPER_DIR: "/Applications/Xcode_14.0.1.app/Contents/Developer"
+ DEVELOPER_DIR: "/Applications/Xcode_14.3.1.app/Contents/Developer"
# Ensure that Linden viewer builds engage Bugsplat.
BUGSPLAT_DB: ${{ needs.setup.outputs.bugsplat_db }}
build_coverity: false
diff --git a/indra/llmath/tests/v3dmath_test.cpp b/indra/llmath/tests/v3dmath_test.cpp
index db08419012..36ad1067a2 100644
--- a/indra/llmath/tests/v3dmath_test.cpp
+++ b/indra/llmath/tests/v3dmath_test.cpp
@@ -504,14 +504,11 @@ namespace tut
template<> template<>
void v3dmath_object::test<24>()
{
-#if LL_WINDOWS && _MSC_VER < 1400
- skip("This fails on VS2003!");
-#else
F64 x = 10., y = 20., z = -15.;
F64 angle1, angle2;
LLVector3d vec3Da(x,y,z), vec3Db(x,y,z);
angle1 = angle_between(vec3Da, vec3Db);
- ensure("1:angle_between: Fail ", (0 == angle1));
+ ensure_approximately_equals_range("1:angle_between: Fail ", angle1, 0., 1.5e-8);
F64 x1 = -1., y1 = -20., z1 = -1.;
vec3Da.clearVec();
vec3Da.setVec(x1,y1,z1);
@@ -520,12 +517,6 @@ namespace tut
vec3Da.normVec();
F64 angle = vec3Db*vec3Da;
angle = acos(angle);
-#if LL_WINDOWS && _MSC_VER > 1900
- skip("This fails on VS2017!");
-#else
- ensure("2:angle_between: Fail ", (angle == angle2));
-#endif
-
-#endif
+ ensure_equals("2:angle_between: Fail ", angle, angle2);
}
}
diff --git a/indra/llui/llemojihelper.cpp b/indra/llui/llemojihelper.cpp
index b9441a9c91..b2c59ce775 100644
--- a/indra/llui/llemojihelper.cpp
+++ b/indra/llui/llemojihelper.cpp
@@ -99,6 +99,7 @@ void LLEmojiHelper::showHelper(LLUICtrl* hostctrl_p, S32 local_x, S32 local_y, c
LLFloater* pHelperFloater = LLFloaterReg::getInstance(DEFAULT_EMOJI_HELPER_FLOATER);
mHelperHandle = pHelperFloater->getHandle();
mHelperCommitConn = pHelperFloater->setCommitCallback(std::bind([&](const LLSD& sdValue) { onCommitEmoji(utf8str_to_wstring(sdValue.asStringRef())[0]); }, std::placeholders::_2));
+ mHelperCloseConn = pHelperFloater->setCloseCallback([this](LLUICtrl* ctrl, const LLSD& param) { onCloseHelper(ctrl, param); });
}
setHostCtrl(hostctrl_p);
mEmojiCommitCb = cb;
@@ -148,6 +149,16 @@ void LLEmojiHelper::onCommitEmoji(llwchar emoji)
}
}
+void LLEmojiHelper::onCloseHelper(LLUICtrl* ctrl, const LLSD& param)
+{
+ mCloseSignal(ctrl, param);
+}
+
+boost::signals2::connection LLEmojiHelper::setCloseCallback(const commit_signal_t::slot_type& cb)
+{
+ return mCloseSignal.connect(cb);
+}
+
void LLEmojiHelper::setHostCtrl(LLUICtrl* hostctrl_p)
{
const LLUICtrl* pCurHostCtrl = mHostHandle.get();
diff --git a/indra/llui/llemojihelper.h b/indra/llui/llemojihelper.h
index 2834b06061..26840eef94 100644
--- a/indra/llui/llemojihelper.h
+++ b/indra/llui/llemojihelper.h
@@ -51,16 +51,23 @@ public:
// Eventing
bool handleKey(const LLUICtrl* ctrl_p, KEY key, MASK mask);
void onCommitEmoji(llwchar emoji);
+ void onCloseHelper(LLUICtrl* ctrl, const LLSD& param);
+
+ typedef boost::signals2::signal<void(LLUICtrl* ctrl, const LLSD& param)> commit_signal_t;
+ boost::signals2::connection setCloseCallback(const commit_signal_t::slot_type& cb);
protected:
LLUICtrl* getHostCtrl() const { return mHostHandle.get(); }
void setHostCtrl(LLUICtrl* hostctrl_p);
private:
+ commit_signal_t mCloseSignal;
+
LLHandle<LLUICtrl> mHostHandle;
LLHandle<LLFloater> mHelperHandle;
boost::signals2::connection mHostCtrlFocusLostConn;
boost::signals2::connection mHelperCommitConn;
+ boost::signals2::connection mHelperCloseConn;
std::function<void(llwchar)> mEmojiCommitCb;
bool mIsHideDisabled;
};
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index ddd1d81cb4..8093536868 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -1105,38 +1105,32 @@ S32 LLScrollListCtrl::getItemIndex( const LLUUID& target_id ) const
void LLScrollListCtrl::selectPrevItem( bool extend_selection)
{
+ updateSort();
+
LLScrollListItem* prev_item = NULL;
- if (!getFirstSelected())
- {
- // select last item
- selectNthItem(getItemCount() - 1);
- }
- else
+ for (LLScrollListItem* item : mItemList)
{
- updateSort();
-
- item_list::iterator iter;
- for (LLScrollListItem* cur_item : mItemList)
+ if (item->getSelected())
{
- if (cur_item->getSelected())
- {
- if (prev_item)
- {
- selectItem(prev_item, cur_item->getSelectedCell(), !extend_selection);
- }
- else
- {
- reportInvalidInput();
- }
- break;
- }
+ break;
+ }
- // don't allow navigation to disabled elements
- prev_item = cur_item->getEnabled() ? cur_item : prev_item;
+ // don't allow navigation to disabled elements
+ if (item->getEnabled())
+ {
+ prev_item = item;
}
}
+ if (!prev_item)
+ {
+ reportInvalidInput();
+ return;
+ }
+
+ selectItem(prev_item, prev_item->getSelectedCell(), !extend_selection);
+
if ((mCommitOnSelectionChange || mCommitOnKeyboardMovement))
{
commitIfChanged();
@@ -1147,36 +1141,41 @@ void LLScrollListCtrl::selectPrevItem( bool extend_selection)
void LLScrollListCtrl::selectNextItem( bool extend_selection)
{
+ updateSort();
+
+ LLScrollListItem* current_item = NULL;
LLScrollListItem* next_item = NULL;
- if (!getFirstSelected())
- {
- selectFirstItem();
- }
- else
+ for (LLScrollListItem* item : mItemList)
{
- updateSort();
-
- for (LLScrollListItem* cur_item : mItemList)
+ if (current_item)
{
- if (cur_item->getSelected())
+ if (item->getEnabled())
{
- if (next_item)
- {
- selectItem(next_item, cur_item->getSelectedCell(), !extend_selection);
- }
- else
- {
- reportInvalidInput();
- }
+ next_item = item;
break;
}
-
- // don't allow navigation to disabled items
- next_item = cur_item->getEnabled() ? cur_item : next_item;
}
+ else if (item->getSelected())
+ {
+ current_item = item;
+ next_item = NULL;
+ continue;
+ }
+ else if (!next_item && item->getEnabled())
+ {
+ next_item = item;
+ }
+ }
+
+ if (!next_item)
+ {
+ reportInvalidInput();
+ return;
}
+ selectItem(next_item, next_item->getSelectedCell(), !extend_selection);
+
if (mCommitOnKeyboardMovement)
{
onCommit();
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index ecac800def..088fbe2744 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -1211,6 +1211,14 @@ void LLTextEditor::showEmojiHelper()
LLEmojiHelper::instance().showHelper(this, cursorRect.mLeft, cursorRect.mTop, LLStringUtil::null, cb);
}
+void LLTextEditor::hideEmojiHelper()
+{
+ if (mShowEmojiHelper)
+ {
+ LLEmojiHelper::instance().hideHelper(this);
+ }
+}
+
void LLTextEditor::tryToShowEmojiHelper()
{
if (mReadOnly || !mShowEmojiHelper)
diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h
index cedb79bf62..32dd95b8ac 100644
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -207,6 +207,7 @@ public:
bool getShowContextMenu() const { return mShowContextMenu; }
void showEmojiHelper();
+ void hideEmojiHelper();
void setShowEmojiHelper(bool show);
bool getShowEmojiHelper() const { return mShowEmojiHelper; }
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index b2f2984c65..6a96dc0c69 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -39,6 +39,7 @@
#include "llchicletbar.h"
#include "lldraghandle.h"
#include "llemojidictionary.h"
+#include "llemojihelper.h"
#include "llfloaterreg.h"
#include "llfloateremojipicker.h"
#include "llfloaterimsession.h"
@@ -298,6 +299,8 @@ bool LLFloaterIMSessionTab::postBuild()
mEmojiPickerShowBtn = getChild<LLButton>("emoji_picker_show_btn");
mEmojiPickerShowBtn->setClickedCallback([this](LLUICtrl*, const LLSD&) { onEmojiPickerShowBtnClicked(); });
+ mEmojiPickerShowBtn->setMouseDownCallback([this](LLUICtrl*, const LLSD&) { onEmojiPickerShowBtnDown(); });
+ mEmojiCloseConn = LLEmojiHelper::instance().setCloseCallback([this](LLUICtrl*, const LLSD&) { onEmojiPickerClosed(); });
mGearBtn = getChild<LLButton>("gear_btn");
mAddBtn = getChild<LLButton>("add_btn");
@@ -526,8 +529,43 @@ void LLFloaterIMSessionTab::onEmojiRecentPanelToggleBtnClicked()
void LLFloaterIMSessionTab::onEmojiPickerShowBtnClicked()
{
- mInputEditor->setFocus(true);
- mInputEditor->showEmojiHelper();
+ if (!mEmojiPickerShowBtn->getToggleState())
+ {
+ mInputEditor->hideEmojiHelper();
+ mInputEditor->setFocus(true);
+ mInputEditor->showEmojiHelper();
+ mEmojiPickerShowBtn->setToggleState(true); // in case hideEmojiHelper closed a visible instance
+ }
+ else
+ {
+ mInputEditor->hideEmojiHelper();
+ mEmojiPickerShowBtn->setToggleState(false);
+ }
+}
+
+void LLFloaterIMSessionTab::onEmojiPickerShowBtnDown()
+{
+ if (mEmojiHelperLastCallbackFrame == LLFrameTimer::getFrameCount())
+ {
+ // Helper gets closed by focus lost event on Down before before onEmojiPickerShowBtnDown
+ // triggers.
+ // If this condition is true, user pressed button and it was 'toggled' during press,
+ // restore 'toggled' state so that button will not reopen helper.
+ mEmojiPickerShowBtn->setToggleState(true);
+ }
+}
+
+void LLFloaterIMSessionTab::onEmojiPickerClosed()
+{
+ if (mEmojiPickerShowBtn->getToggleState())
+ {
+ mEmojiPickerShowBtn->setToggleState(false);
+ // Helper gets closed by focus lost event on Down before onEmojiPickerShowBtnDown
+ // triggers. If mEmojiHelperLastCallbackFrame is set and matches Down, means close
+ // was triggered by user's press.
+ // A bit hacky, but I can't think of a better way to handle this without rewriting helper.
+ mEmojiHelperLastCallbackFrame = LLFrameTimer::getFrameCount();
+ }
}
void LLFloaterIMSessionTab::initEmojiRecentPanel()
diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h
index bee5c8c2c4..890c920bbe 100644
--- a/indra/newview/llfloaterimsessiontab.h
+++ b/indra/newview/llfloaterimsessiontab.h
@@ -227,6 +227,8 @@ private:
void onEmojiRecentPanelToggleBtnClicked();
void onEmojiPickerShowBtnClicked();
+ void onEmojiPickerShowBtnDown();
+ void onEmojiPickerClosed();
void initEmojiRecentPanel();
void onEmojiRecentPanelFocusReceived();
void onEmojiRecentPanelFocusLost();
@@ -241,6 +243,9 @@ private:
S32 mInputEditorPad;
S32 mChatLayoutPanelHeight;
S32 mFloaterHeight;
+
+ boost::signals2::connection mEmojiCloseConn;
+ U32 mEmojiHelperLastCallbackFrame = { 0 };
};
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 896c7d8d70..2deb7caad5 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -4189,6 +4189,32 @@ void LLFolderBridge::pasteLinkFromClipboard()
std::vector<LLUUID> objects;
LLClipboard::instance().pasteFromClipboard(objects);
+ if (objects.size() == 0)
+ {
+ LLClipboard::instance().setCutMode(false);
+ return;
+ }
+
+ LLUUID& first_id = objects[0];
+ LLInventoryItem* item = model->getItem(first_id);
+ if (item && item->getAssetUUID().isNull())
+ {
+ if (item->getActualType() == LLAssetType::AT_NOTECARD)
+ {
+ // otehrwise AIS will return 'Cannot link to items with a NULL asset_id.'
+ LLNotificationsUtil::add("CantLinkNotecard");
+ LLClipboard::instance().setCutMode(false);
+ return;
+ }
+ else if (item->getActualType() == LLAssetType::AT_MATERIAL)
+ {
+ LLNotificationsUtil::add("CantLinkMaterial");
+ LLClipboard::instance().setCutMode(false);
+ return;
+ }
+ }
+
+
LLPointer<LLInventoryCallback> cb = NULL;
LLInventoryPanel* panel = mInventoryPanel.get();
if (panel->getRootFolder()->isSingleFolderMode())
diff --git a/indra/newview/llinventorygallery.cpp b/indra/newview/llinventorygallery.cpp
index c4f93cee98..03bafa48bd 100644
--- a/indra/newview/llinventorygallery.cpp
+++ b/indra/newview/llinventorygallery.cpp
@@ -2105,6 +2105,30 @@ void LLInventoryGallery::pasteAsLink()
std::vector<LLUUID> objects;
LLClipboard::instance().pasteFromClipboard(objects);
+ if (objects.size() == 0)
+ {
+ LLClipboard::instance().setCutMode(false);
+ return;
+ }
+
+ LLUUID& first_id = objects[0];
+ LLInventoryItem* item = gInventory.getItem(first_id);
+ if (item && item->getAssetUUID().isNull())
+ {
+ if (item->getActualType() == LLAssetType::AT_NOTECARD)
+ {
+ LLNotificationsUtil::add("CantLinkNotecard");
+ LLClipboard::instance().setCutMode(false);
+ return;
+ }
+ else if (item->getActualType() == LLAssetType::AT_MATERIAL)
+ {
+ LLNotificationsUtil::add("CantLinkMaterial");
+ LLClipboard::instance().setCutMode(false);
+ return;
+ }
+ }
+
bool paste_into_root = mSelectedItemIDs.empty();
for (LLUUID& dest : mSelectedItemIDs)
{
diff --git a/indra/newview/llinventorygallerymenu.cpp b/indra/newview/llinventorygallerymenu.cpp
index c84b9abba0..340ecfcbbc 100644
--- a/indra/newview/llinventorygallerymenu.cpp
+++ b/indra/newview/llinventorygallerymenu.cpp
@@ -598,20 +598,23 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men
bool has_children = false;
bool is_full_perm_item = false;
bool is_copyable = false;
- LLViewerInventoryItem* selected_item = gInventory.getItem(selected_id);
+
+ LLViewerInventoryCategory* selected_category = nullptr;
+ LLViewerInventoryItem* selected_item = nullptr;
if(is_folder)
{
- LLInventoryCategory* category = gInventory.getCategory(selected_id);
- if (category)
+ selected_category = dynamic_cast<LLViewerInventoryCategory*>(obj);
+ if (selected_category)
{
- folder_type = category->getPreferredType();
+ folder_type = selected_category->getPreferredType();
is_system_folder = LLFolderType::lookupIsProtectedType(folder_type);
has_children = (gInventory.categoryHasChildren(selected_id) != LLInventoryModel::CHILDREN_NO);
}
}
else
{
+ selected_item = dynamic_cast<LLViewerInventoryItem*>(obj);
if (selected_item)
{
is_full_perm_item = selected_item->getIsFullPerm();
@@ -730,8 +733,7 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men
{
if (is_agent_inventory && !is_inbox && !is_cof && !is_in_favorites && !is_outfits)
{
- LLViewerInventoryCategory* category = gInventory.getCategory(selected_id);
- if (!category || !LLFriendCardsManager::instance().isCategoryInFriendFolder(category))
+ if (!selected_category || !LLFriendCardsManager::instance().isCategoryInFriendFolder(selected_category))
{
items.push_back(std::string("New Folder"));
}
@@ -759,6 +761,22 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men
if (inventory_linking)
{
items.push_back(std::string("Paste As Link"));
+
+ if (selected_item)
+ {
+ if (!LLAssetType::lookupCanLink(selected_item->getActualType()))
+ {
+ disabled_items.push_back(std::string("Paste As Link"));
+ }
+ else if (gInventory.isObjectDescendentOf(selected_item->getUUID(), gInventory.getLibraryRootFolderID()))
+ {
+ disabled_items.push_back(std::string("Paste As Link"));
+ }
+ }
+ else if (selected_category && LLFolderType::lookupIsProtectedType(selected_category->getPreferredType()))
+ {
+ disabled_items.push_back(std::string("Paste As Link"));
+ }
}
}
if (is_folder && is_agent_inventory)
@@ -979,9 +997,8 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men
{
if (is_folder)
{
- LLViewerInventoryCategory* cat = gInventory.getCategory(selected_id);
- if (cat
- && !LLFolderType::lookupIsProtectedType(cat->getPreferredType())
+ if (selected_category
+ && !LLFolderType::lookupIsProtectedType(selected_category->getPreferredType())
&& gInventory.isObjectDescendentOf(selected_id, gInventory.getRootFolderID()))
{
can_list = true;
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 071f6458c5..bc817765cf 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -6532,6 +6532,22 @@ Do you want to replace it with the selected object?
</notification>
<notification
+ icon="alertmodal.tga"
+ name="CantLinkNotecard"
+ type="alertmodal">
+ You must save the notecard before creating a link to it.
+ <tag>fail</tag>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantLinkMaterial"
+ type="alertmodal">
+ You must save the material before creating a link to it.
+ <tag>fail</tag>
+ </notification>
+
+ <notification
icon="alert.tga"
label="Do Not Disturb Mode Warning"
name="DoNotDisturbModePay"
diff --git a/indra/test/lltut.h b/indra/test/lltut.h
index fbf60444be..986bdd0619 100644
--- a/indra/test/lltut.h
+++ b/indra/test/lltut.h
@@ -30,8 +30,10 @@
#define LL_LLTUT_H
#include "is_approx_equal_fraction.h" // instead of llmath.h
+#include "stringize.h"
#include <cstring>
#include <string>
+#include <string_view>
#include <vector>
class LLDate;
@@ -89,49 +91,38 @@ namespace tut
// The functions BELOW this point actually consume tut.hpp functionality.
namespace tut
{
- inline void ensure_approximately_equals(const char* msg, F64 actual, F64 expected, U32 frac_bits)
+ template <typename F> // replace with C++20 floating-point concept
+ inline void ensure_approximately_equals(std::string_view msg, F actual, F expected, U32 frac_bits)
{
if(!is_approx_equal_fraction(actual, expected, frac_bits))
{
- std::stringstream ss;
- ss << (msg?msg:"") << (msg?": ":"") << "not equal actual: " << actual << " expected: " << expected;
- throw tut::failure(ss.str().c_str());
+ throw tut::failure(stringize(msg, (msg.empty()?"":": "), "not equal actual: ",
+ actual, " expected: ", expected));
}
}
- inline void ensure_approximately_equals(const char* msg, F32 actual, F32 expected, U32 frac_bits)
+ template <typename F> // replace with C++20 floating-point concept
+ inline void ensure_approximately_equals(F actual, F expected, U32 frac_bits)
{
- if(!is_approx_equal_fraction(actual, expected, frac_bits))
- {
- std::stringstream ss;
- ss << (msg?msg:"") << (msg?": ":"") << "not equal actual: " << actual << " expected: " << expected;
- throw tut::failure(ss.str().c_str());
- }
- }
-
- inline void ensure_approximately_equals(F32 actual, F32 expected, U32 frac_bits)
- {
- ensure_approximately_equals(NULL, actual, expected, frac_bits);
+ ensure_approximately_equals("", actual, expected, frac_bits);
}
- inline void ensure_approximately_equals_range(const char *msg, F32 actual, F32 expected, F32 delta)
+ template <typename F> // replace with C++20 floating-point concept
+ inline void ensure_approximately_equals_range(std::string_view msg, F actual, F expected, F delta)
{
if (fabs(actual-expected)>delta)
{
- std::stringstream ss;
- ss << (msg?msg:"") << (msg?": ":"") << "not equal actual: " << actual << " expected: " << expected << " tolerance: " << delta;
- throw tut::failure(ss.str().c_str());
+ throw tut::failure(stringize(msg, (msg.empty()?"":": "), "not equal actual: ",
+ actual, " expected: ", expected, " tolerance: ", delta));
}
}
- inline void ensure_memory_matches(const char* msg,const void* actual, U32 actual_len, const void* expected,U32 expected_len)
+ inline void ensure_memory_matches(std::string_view msg,const void* actual, U32 actual_len, const void* expected,U32 expected_len)
{
if((expected_len != actual_len) ||
(std::memcmp(actual, expected, actual_len) != 0))
{
- std::stringstream ss;
- ss << (msg?msg:"") << (msg?": ":"") << "not equal";
- throw tut::failure(ss.str().c_str());
+ throw tut::failure(stringize(msg, (msg.empty()?"":": "), "not equal"));
}
}
@@ -141,20 +132,18 @@ namespace tut
}
template <class T,class Q>
- void ensure_not_equals(const char* msg,const Q& actual,const T& expected)
+ void ensure_not_equals(std::string_view msg,const Q& actual,const T& expected)
{
if( expected == actual )
{
- std::stringstream ss;
- ss << (msg?msg:"") << (msg?": ":"") << "both equal " << expected;
- throw tut::failure(ss.str().c_str());
+ throw tut::failure(stringize(msg, (msg.empty()?"":": "), "both equal ", expected));
}
}
template <class T,class Q>
void ensure_not_equals(const Q& actual,const T& expected)
{
- ensure_not_equals(NULL, actual, expected);
+ ensure_not_equals("", actual, expected);
}
}