diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp index ea8ff2ce43..38cdfa73fb 100644 --- a/src/tokenizer.cpp +++ b/src/tokenizer.cpp @@ -68,6 +68,28 @@ Tokenizer::Tokenizer(Tokenizer && rhs) : reset(); } +Tokenizer& Tokenizer::operator=(const Tokenizer& other) +{ + Tokenizer tmp(other); + swap(tmp); + return *this; +} + +Tokenizer& Tokenizer::operator=(Tokenizer&& other) +{ + Tokenizer tmp(std::move(other)); + swap(tmp); + return *this; +} + +void Tokenizer::swap(Tokenizer& other) +{ + std::swap(text, other.text); + std::swap(separators, other.separators); + std::swap(start, other.start); + std::swap(ntokens, other.ntokens); +} + /*! Re-position the tokenizer state to the first word, * i.e. the first non-separator character */ void Tokenizer::reset() { @@ -181,6 +203,25 @@ ValueTokenizer::ValueTokenizer(const ValueTokenizer &rhs) : tokens(rhs.tokens) { ValueTokenizer::ValueTokenizer(ValueTokenizer &&rhs) : tokens(std::move(rhs.tokens)) { } +ValueTokenizer& ValueTokenizer::operator=(const ValueTokenizer& other) +{ + ValueTokenizer tmp(other); + swap(tmp); + return *this; +} + +ValueTokenizer& ValueTokenizer::operator=(ValueTokenizer&& other) +{ + ValueTokenizer tmp(std::move(other)); + swap(tmp); + return *this; +} + +void ValueTokenizer::swap(ValueTokenizer& other) +{ + std::swap(tokens, other.tokens); +} + /*! Indicate whether more tokens are available * * \return true if there are more tokens, false if not */ diff --git a/src/tokenizer.h b/src/tokenizer.h index a17ab13d04..8cc6d2d42b 100644 --- a/src/tokenizer.h +++ b/src/tokenizer.h @@ -37,8 +37,9 @@ public: Tokenizer(const std::string &str, const std::string &separators = TOKENIZER_DEFAULT_SEPARATORS); Tokenizer(Tokenizer &&); Tokenizer(const Tokenizer &); - Tokenizer& operator=(const Tokenizer&) = default; - Tokenizer& operator=(Tokenizer&&) = default; + Tokenizer& operator=(const Tokenizer&); + Tokenizer& operator=(Tokenizer&&); + void swap(Tokenizer &); void reset(); void skip(int n=1); @@ -93,8 +94,9 @@ public: ValueTokenizer(const std::string &str, const std::string &separators = TOKENIZER_DEFAULT_SEPARATORS); ValueTokenizer(const ValueTokenizer &); ValueTokenizer(ValueTokenizer &&); - ValueTokenizer& operator=(const ValueTokenizer&) = default; - ValueTokenizer& operator=(ValueTokenizer&&) = default; + ValueTokenizer& operator=(const ValueTokenizer&); + ValueTokenizer& operator=(ValueTokenizer&&); + void swap(ValueTokenizer &); std::string next_string(); tagint next_tagint(); diff --git a/unittest/utils/test_tokenizer.cpp b/unittest/utils/test_tokenizer.cpp index 5b20d24e7c..275a86a05f 100644 --- a/unittest/utils/test_tokenizer.cpp +++ b/unittest/utils/test_tokenizer.cpp @@ -101,6 +101,38 @@ TEST(Tokenizer, move_constructor) ASSERT_EQ(u.count(), 3); } +TEST(Tokenizer, copy_assignment) +{ + Tokenizer t(" test word ", " "); + Tokenizer u(" test2 word2 other2 ", " "); + ASSERT_THAT(t.next(), Eq("test")); + ASSERT_THAT(t.next(), Eq("word")); + ASSERT_EQ(t.count(), 2); + Tokenizer v = u; + u = t; + ASSERT_THAT(u.next(), Eq("test")); + ASSERT_THAT(u.next(), Eq("word")); + ASSERT_EQ(u.count(), 2); + + ASSERT_THAT(v.next(), Eq("test2")); + ASSERT_THAT(v.next(), Eq("word2")); + ASSERT_THAT(v.next(), Eq("other2")); + ASSERT_EQ(v.count(), 3); +} + +TEST(Tokenizer, move_assignment) +{ + Tokenizer t(" test word ", " "); + ASSERT_THAT(t.next(), Eq("test")); + ASSERT_THAT(t.next(), Eq("word")); + ASSERT_EQ(t.count(), 2); + t = Tokenizer("test new word ", " "); + ASSERT_THAT(t.next(), Eq("test")); + ASSERT_THAT(t.next(), Eq("new")); + ASSERT_THAT(t.next(), Eq("word")); + ASSERT_EQ(t.count(), 3); +} + TEST(Tokenizer, no_separator_path) { Tokenizer t("one", ":"); @@ -223,6 +255,38 @@ TEST(ValueTokenizer, move_constructor) ASSERT_EQ(u.count(), 3); } +TEST(ValueTokenizer, copy_assignment) +{ + ValueTokenizer t(" test word ", " "); + ValueTokenizer u(" test2 word2 other2 ", " "); + ASSERT_THAT(t.next_string(), Eq("test")); + ASSERT_THAT(t.next_string(), Eq("word")); + ASSERT_EQ(t.count(), 2); + ValueTokenizer v = u; + u = t; + ASSERT_THAT(u.next_string(), Eq("test")); + ASSERT_THAT(u.next_string(), Eq("word")); + ASSERT_EQ(u.count(), 2); + + ASSERT_THAT(v.next_string(), Eq("test2")); + ASSERT_THAT(v.next_string(), Eq("word2")); + ASSERT_THAT(v.next_string(), Eq("other2")); + ASSERT_EQ(v.count(), 3); +} + +TEST(ValueTokenizer, move_assignment) +{ + ValueTokenizer t(" test word ", " "); + ASSERT_THAT(t.next_string(), Eq("test")); + ASSERT_THAT(t.next_string(), Eq("word")); + ASSERT_EQ(t.count(), 2); + t = ValueTokenizer("test new word ", " "); + ASSERT_THAT(t.next_string(), Eq("test")); + ASSERT_THAT(t.next_string(), Eq("new")); + ASSERT_THAT(t.next_string(), Eq("word")); + ASSERT_EQ(t.count(), 3); +} + TEST(ValueTokenizer, bad_integer) { ValueTokenizer values("f10 f11 f12");