Index: include/__hash_table =================================================================== --- include/__hash_table +++ include/__hash_table @@ -100,22 +100,6 @@ return size_t(1) << (std::numeric_limits::digits - __clz(__n-1)); } -#ifndef _LIBCPP_CXX03_LANG -struct __extract_key_fail_tag {}; -struct __extract_key_self_tag {}; -struct __extract_key_first_tag {}; - -template ::type> -struct __can_extract_key - : conditional::value, __extract_key_self_tag, - __extract_key_fail_tag>::type {}; - -template -struct __can_extract_key<_Pair, _Key, pair<_First, _Second>> - : conditional::type, _Key>::value, - __extract_key_first_tag, __extract_key_fail_tag>::type {}; -#endif template class __hash_table; Index: include/__tree =================================================================== --- include/__tree +++ include/__tree @@ -1064,16 +1064,85 @@ __emplace_hint_unique_key_args(const_iterator, _Key const&, _Args&&...); template - pair __emplace_unique(_Args&&... __args); + pair __emplace_unique_impl(_Args&&... __args); template - iterator __emplace_hint_unique(const_iterator __p, _Args&&... __args); + iterator __emplace_hint_unique_impl(const_iterator __p, _Args&&... __args); template iterator __emplace_multi(_Args&&... __args); template iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args); + + template + _LIBCPP_INLINE_VISIBILITY + pair __emplace_unique(_Pp&& __x) { + return __emplace_unique_extract_key(_VSTD::forward<_Pp>(__x), + __can_extract_key<_Pp, key_type>()); + } + + template + _LIBCPP_INLINE_VISIBILITY + pair __emplace_unique(_Args&&... __args) { + return __emplace_unique_impl(_VSTD::forward<_Args>(__args)...); + } + + template + _LIBCPP_INLINE_VISIBILITY + pair + __emplace_unique_extract_key(_Pp&& __x, __extract_key_fail_tag) { + return __emplace_unique_impl(_VSTD::forward<_Pp>(__x)); + } + + template + _LIBCPP_INLINE_VISIBILITY + pair + __emplace_unique_extract_key(_Pp&& __x, __extract_key_self_tag) { + return __emplace_unique_key_args(__x, _VSTD::forward<_Pp>(__x)); + } + + template + _LIBCPP_INLINE_VISIBILITY + pair + __emplace_unique_extract_key(_Pp&& __x, __extract_key_first_tag) { + return __emplace_unique_key_args(__x.first, _VSTD::forward<_Pp>(__x)); + } + + template + _LIBCPP_INLINE_VISIBILITY + iterator __emplace_hint_unique(const_iterator __p, _Pp&& __x) { + return __emplace_hint_unique_extract_key(__p, _VSTD::forward<_Pp>(__x), + __can_extract_key<_Pp, key_type>()); + } + + template + _LIBCPP_INLINE_VISIBILITY + iterator __emplace_hint_unique(const_iterator __p, _Args&&... __args) { + return __emplace_hint_unique_impl(__p, _VSTD::forward<_Args>(__args)...); + } + + template + _LIBCPP_INLINE_VISIBILITY + iterator + __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_fail_tag) { + return __emplace_hint_unique_impl(__p, _VSTD::forward<_Pp>(__x)); + } + + template + _LIBCPP_INLINE_VISIBILITY + iterator + __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_self_tag) { + return __emplace_hint_unique_key_args(__p, __x, _VSTD::forward<_Pp>(__x)); + } + + template + _LIBCPP_INLINE_VISIBILITY + iterator + __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_first_tag) { + return __emplace_hint_unique_key_args(__p, __x.first, _VSTD::forward<_Pp>(__x)); + } + #else template _LIBCPP_INLINE_VISIBILITY @@ -1989,7 +2058,7 @@ template template pair::iterator, bool> -__tree<_Tp, _Compare, _Allocator>::__emplace_unique(_Args&&... __args) +__tree<_Tp, _Compare, _Allocator>::__emplace_unique_impl(_Args&&... __args) { __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); __node_base_pointer __parent; @@ -2008,7 +2077,7 @@ template template typename __tree<_Tp, _Compare, _Allocator>::iterator -__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique(const_iterator __p, _Args&&... __args) +__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_impl(const_iterator __p, _Args&&... __args) { __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); __node_base_pointer __parent; Index: include/__tuple =================================================================== --- include/__tuple +++ include/__tuple @@ -95,8 +95,6 @@ // pair specializations -template struct _LIBCPP_TYPE_VIS_ONLY pair; - template struct __tuple_like > : true_type {}; template Index: include/type_traits =================================================================== --- include/type_traits +++ include/type_traits @@ -368,6 +368,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD +template struct _LIBCPP_TYPE_VIS_ONLY pair; + template struct __void_t { typedef void type; }; @@ -4434,6 +4436,24 @@ # endif // _LIBCPP_HAS_NO_VARIADICS #endif // _LIBCPP_STD_VER > 14 +// These traits are used in __tree and __hash_table +#ifndef _LIBCPP_CXX03_LANG +struct __extract_key_fail_tag {}; +struct __extract_key_self_tag {}; +struct __extract_key_first_tag {}; + +template ::type> +struct __can_extract_key + : conditional::value, __extract_key_self_tag, + __extract_key_fail_tag>::type {}; + +template +struct __can_extract_key<_Pair, _Key, pair<_First, _Second>> + : conditional::type, _Key>::value, + __extract_key_first_tag, __extract_key_fail_tag>::type {}; +#endif + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_TYPE_TRAITS Index: test/std/containers/associative/map/map.modifiers/insert_allocator_requirements.pass.cpp =================================================================== --- test/std/containers/associative/map/map.modifiers/insert_allocator_requirements.pass.cpp +++ /dev/null @@ -1,137 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// - -// class map - -// insert(...); - -// UNSUPPORTED: c++98, c++03 - -#include -#include -#include - -#include "test_macros.h" -#include "count_new.hpp" -#include "container_test_types.h" - -template -void PrintInfo(int line, Arg&& arg) -{ - std::cout << "In " << __FILE__ << ":" << line << ":\n " << arg << "\n" << std::endl; -} -#define PRINT(msg) PrintInfo(__LINE__, msg) - -template -void testContainerInsert() -{ - typedef typename Container::value_type ValueTp; - typedef Container C; - typedef std::pair R; - ConstructController* cc = getConstructController(); - cc->reset(); - { - PRINT("Testing C::insert(const value_type&)"); - Container c; - const ValueTp v(42, 1); - cc->expect(); - assert(c.insert(v).second); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - const ValueTp v2(42, 1); - assert(c.insert(v2).second == false); - } - } - { - PRINT("Testing C::insert(value_type&)"); - Container c; - ValueTp v(42, 1); - cc->expect(); - assert(c.insert(v).second); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - ValueTp v2(42, 1); - assert(c.insert(v2).second == false); - } - } - { - PRINT("Testing C::insert(value_type&&)"); - Container c; - ValueTp v(42, 1); - cc->expect(); - assert(c.insert(std::move(v)).second); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - ValueTp v2(42, 1); - assert(c.insert(std::move(v2)).second == false); - } - } - { - PRINT("Testing C::insert(std::initializer_list)"); - Container c; - std::initializer_list il = { ValueTp(1, 1), ValueTp(2, 1) }; - cc->expect(2); - c.insert(il); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - c.insert(il); - } - } - { - PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type const&"); - Container c; - const ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1), ValueTp(3, 1) }; - cc->expect(3); - c.insert(std::begin(ValueList), std::end(ValueList)); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - c.insert(std::begin(ValueList), std::end(ValueList)); - } - } - { - PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type&&"); - Container c; - ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1) , ValueTp(3, 1) }; - cc->expect(3); - c.insert(std::move_iterator(std::begin(ValueList)), - std::move_iterator(std::end(ValueList))); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - ValueTp ValueList2[] = { ValueTp(1, 1), ValueTp(2, 1) , ValueTp(3, 1) }; - c.insert(std::move_iterator(std::begin(ValueList2)), - std::move_iterator(std::end(ValueList2))); - } - } - { - PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type&"); - Container c; - ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1) , ValueTp(3, 1) }; - cc->expect(3); - c.insert(std::begin(ValueList), std::end(ValueList)); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - c.insert(std::begin(ValueList), std::end(ValueList)); - } - } -} - - -int main() -{ - testContainerInsert >(); -} Index: test/std/containers/associative/map/map.modifiers/insert_and_emplace_allocator_requirements.pass.cpp =================================================================== --- /dev/null +++ test/std/containers/associative/map/map.modifiers/insert_and_emplace_allocator_requirements.pass.cpp @@ -0,0 +1,360 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// class map + +// insert(...); +// emplace(...); +// emplace_hint(...); + +// UNSUPPORTED: c++98, c++03 + +#include +#include +#include + +#include "test_macros.h" +#include "count_new.hpp" +#include "container_test_types.h" + +template +void PrintInfo(int line, Arg&& arg) +{ + std::cout << "In " << __FILE__ << ":" << line << ":\n " << arg << "\n" << std::endl; +} +#define PRINT(msg) PrintInfo(__LINE__, msg) + +template +void testContainerInsert() +{ + typedef typename Container::value_type ValueTp; + typedef Container C; + typedef std::pair R; + ConstructController* cc = getConstructController(); + cc->reset(); + { + PRINT("Testing C::insert(const value_type&)"); + Container c; + const ValueTp v(42, 1); + cc->expect(); + assert(c.insert(v).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const ValueTp v2(42, 1); + assert(c.insert(v2).second == false); + } + } + { + PRINT("Testing C::insert(value_type&)"); + Container c; + ValueTp v(42, 1); + cc->expect(); + assert(c.insert(v).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + ValueTp v2(42, 1); + assert(c.insert(v2).second == false); + } + } + { + PRINT("Testing C::insert(value_type&&)"); + Container c; + ValueTp v(42, 1); + cc->expect(); + assert(c.insert(std::move(v)).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + ValueTp v2(42, 1); + assert(c.insert(std::move(v2)).second == false); + } + } + { + PRINT("Testing C::insert(const value_type&&)"); + Container c; + const ValueTp v(42, 1); + cc->expect(); + assert(c.insert(std::move(v)).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const ValueTp v2(42, 1); + assert(c.insert(std::move(v2)).second == false); + } + } + { + PRINT("Testing C::insert(std::initializer_list)"); + Container c; + std::initializer_list il = { ValueTp(1, 1), ValueTp(2, 1) }; + cc->expect(2); + c.insert(il); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + c.insert(il); + } + } + { + PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type const&"); + Container c; + const ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1), ValueTp(3, 1) }; + cc->expect(3); + c.insert(std::begin(ValueList), std::end(ValueList)); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + c.insert(std::begin(ValueList), std::end(ValueList)); + } + } + { + PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type&&"); + Container c; + ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1) , ValueTp(3, 1) }; + cc->expect(3); + c.insert(std::move_iterator(std::begin(ValueList)), + std::move_iterator(std::end(ValueList))); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + ValueTp ValueList2[] = { ValueTp(1, 1), ValueTp(2, 1) , ValueTp(3, 1) }; + c.insert(std::move_iterator(std::begin(ValueList2)), + std::move_iterator(std::end(ValueList2))); + } + } + { + PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type&"); + Container c; + ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1) , ValueTp(3, 1) }; + cc->expect(3); + c.insert(std::begin(ValueList), std::end(ValueList)); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + c.insert(std::begin(ValueList), std::end(ValueList)); + } + } +} + +template +void testContainerEmplace() +{ + typedef typename Container::value_type ValueTp; + typedef typename Container::key_type Key; + typedef typename Container::mapped_type Mapped; + typedef typename std::pair NonConstKeyPair; + typedef Container C; + typedef std::pair R; + ConstructController* cc = getConstructController(); + cc->reset(); + { + PRINT("Testing C::emplace(const value_type&)"); + Container c; + const ValueTp v(42, 1); + cc->expect(); + assert(c.emplace(v).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const ValueTp v2(42, 1); + assert(c.emplace(v2).second == false); + } + } + { + PRINT("Testing C::emplace(value_type&)"); + Container c; + ValueTp v(42, 1); + cc->expect(); + assert(c.emplace(v).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + ValueTp v2(42, 1); + assert(c.emplace(v2).second == false); + } + } + { + PRINT("Testing C::emplace(value_type&&)"); + Container c; + ValueTp v(42, 1); + cc->expect(); + assert(c.emplace(std::move(v)).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + ValueTp v2(42, 1); + assert(c.emplace(std::move(v2)).second == false); + } + } + { + PRINT("Testing C::emplace(const value_type&&)"); + Container c; + const ValueTp v(42, 1); + cc->expect(); + assert(c.emplace(std::move(v)).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const ValueTp v2(42, 1); + assert(c.emplace(std::move(v2)).second == false); + } + } + { + PRINT("Testing C::emplace(pair const&)"); + Container c; + const NonConstKeyPair v(42, 1); + cc->expect(); + assert(c.emplace(v).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const NonConstKeyPair v2(42, 1); + assert(c.emplace(v2).second == false); + } + } + { + PRINT("Testing C::emplace(pair &&)"); + Container c; + NonConstKeyPair v(42, 1); + cc->expect(); + assert(c.emplace(std::move(v)).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + NonConstKeyPair v2(42, 1); + assert(c.emplace(std::move(v2)).second == false); + } + } +} + + +template +void testContainerEmplaceHint() +{ + typedef typename Container::value_type ValueTp; + typedef typename Container::key_type Key; + typedef typename Container::mapped_type Mapped; + typedef typename std::pair NonConstKeyPair; + typedef Container C; + typedef typename C::iterator It; + ConstructController* cc = getConstructController(); + cc->reset(); + { + PRINT("Testing C::emplace_hint(p, const value_type&)"); + Container c; + const ValueTp v(42, 1); + cc->expect(); + It ret = c.emplace_hint(c.end(), v); + assert(ret != c.end()); + assert(c.size() == 1); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const ValueTp v2(42, 1); + It ret2 = c.emplace_hint(c.begin(), v2); + assert(&(*ret2) == &(*ret)); + assert(c.size() == 1); + } + } + { + PRINT("Testing C::emplace_hint(p, value_type&)"); + Container c; + ValueTp v(42, 1); + cc->expect(); + It ret = c.emplace_hint(c.end(), v); + assert(ret != c.end()); + assert(c.size() == 1); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + ValueTp v2(42, 1); + It ret2 = c.emplace_hint(c.begin(), v2); + assert(&(*ret2) == &(*ret)); + assert(c.size() == 1); + } + } + { + PRINT("Testing C::emplace_hint(p, value_type&&)"); + Container c; + ValueTp v(42, 1); + cc->expect(); + It ret = c.emplace_hint(c.end(), std::move(v)); + assert(ret != c.end()); + assert(c.size() == 1); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + ValueTp v2(42, 1); + It ret2 = c.emplace_hint(c.begin(), std::move(v2)); + assert(&(*ret2) == &(*ret)); + assert(c.size() == 1); + } + } + { + PRINT("Testing C::emplace_hint(p, const value_type&&)"); + Container c; + const ValueTp v(42, 1); + cc->expect(); + It ret = c.emplace_hint(c.end(), std::move(v)); + assert(ret != c.end()); + assert(c.size() == 1); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const ValueTp v2(42, 1); + It ret2 = c.emplace_hint(c.begin(), std::move(v2)); + assert(&(*ret2) == &(*ret)); + assert(c.size() == 1); + } + } + { + PRINT("Testing C::emplace_hint(p, pair const&)"); + Container c; + const NonConstKeyPair v(42, 1); + cc->expect(); + It ret = c.emplace_hint(c.end(), v); + assert(ret != c.end()); + assert(c.size() == 1); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const NonConstKeyPair v2(42, 1); + It ret2 = c.emplace_hint(c.begin(), v2); + assert(&(*ret2) == &(*ret)); + assert(c.size() == 1); + } + } + { + PRINT("Testing C::emplace_hint(p, pair&&)"); + Container c; + NonConstKeyPair v(42, 1); + cc->expect(); + It ret = c.emplace_hint(c.end(), std::move(v)); + assert(ret != c.end()); + assert(c.size() == 1); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + NonConstKeyPair v2(42, 1); + It ret2 = c.emplace_hint(c.begin(), std::move(v2)); + assert(&(*ret2) == &(*ret)); + assert(c.size() == 1); + } + } +} + +int main() +{ + testContainerInsert >(); + testContainerEmplace >(); + testContainerEmplaceHint >(); +} Index: test/std/containers/associative/set/insert_allocator_requirements.pass.cpp =================================================================== --- test/std/containers/associative/set/insert_allocator_requirements.pass.cpp +++ /dev/null @@ -1,137 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// - -// class set - -// insert(...) - -// UNSUPPORTED: c++98, c++03 - -#include -#include -#include - -#include "test_macros.h" -#include "count_new.hpp" -#include "container_test_types.h" - -template -void PrintInfo(int line, Arg&& arg) -{ - std::cout << "In " << __FILE__ << ":" << line << ":\n " << arg << "\n" << std::endl; -} -#define PRINT(msg) PrintInfo(__LINE__, msg) - -template -void testContainerInsert() -{ - typedef typename Container::value_type ValueTp; - typedef Container C; - typedef std::pair R; - ConstructController* cc = getConstructController(); - cc->reset(); - { - PRINT("Testing C::insert(const value_type&)"); - Container c; - const ValueTp v(42); - cc->expect(); - assert(c.insert(v).second); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - const ValueTp v2(42); - assert(c.insert(v2).second == false); - } - } - { - PRINT("Testing C::insert(value_type&)"); - Container c; - ValueTp v(42); - cc->expect(); - assert(c.insert(v).second); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - ValueTp v2(42); - assert(c.insert(v2).second == false); - } - } - { - PRINT("Testing C::insert(value_type&&)"); - Container c; - ValueTp v(42); - cc->expect(); - assert(c.insert(std::move(v)).second); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - ValueTp v2(42); - assert(c.insert(std::move(v2)).second == false); - } - } - { - PRINT("Testing C::insert(std::initializer_list)"); - Container c; - std::initializer_list il = { ValueTp(1), ValueTp(2) }; - cc->expect(2); - c.insert(il); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - c.insert(il); - } - } - { - PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type const&"); - Container c; - const ValueTp ValueList[] = { ValueTp(1), ValueTp(2), ValueTp(3) }; - cc->expect(3); - c.insert(std::begin(ValueList), std::end(ValueList)); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - c.insert(std::begin(ValueList), std::end(ValueList)); - } - } - { - PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type&&"); - Container c; - ValueTp ValueList[] = { ValueTp(1), ValueTp(2) , ValueTp(3) }; - cc->expect(3); - c.insert(std::move_iterator(std::begin(ValueList)), - std::move_iterator(std::end(ValueList))); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - ValueTp ValueList2[] = { ValueTp(1), ValueTp(2) , ValueTp(3) }; - c.insert(std::move_iterator(std::begin(ValueList2)), - std::move_iterator(std::end(ValueList2))); - } - } - { - PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type&"); - Container c; - ValueTp ValueList[] = { ValueTp(1), ValueTp(2) , ValueTp(3) }; - cc->expect(3); - c.insert(std::begin(ValueList), std::end(ValueList)); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - c.insert(std::begin(ValueList), std::end(ValueList)); - } - } -} - - -int main() -{ - testContainerInsert >(); -} Index: test/std/containers/associative/set/insert_and_emplace_allocator_requirements.pass.cpp =================================================================== --- /dev/null +++ test/std/containers/associative/set/insert_and_emplace_allocator_requirements.pass.cpp @@ -0,0 +1,297 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// class set + +// insert(...) +// emplace(...) +// emplace_hint(...) + +// UNSUPPORTED: c++98, c++03 + +#include +#include +#include + +#include "test_macros.h" +#include "count_new.hpp" +#include "container_test_types.h" + +template +void PrintInfo(int line, Arg&& arg) +{ + std::cout << "In " << __FILE__ << ":" << line << ":\n " << arg << "\n" << std::endl; +} +#define PRINT(msg) PrintInfo(__LINE__, msg) + +template +void testContainerInsert() +{ + typedef typename Container::value_type ValueTp; + typedef Container C; + typedef std::pair R; + ConstructController* cc = getConstructController(); + cc->reset(); + { + PRINT("Testing C::insert(const value_type&)"); + Container c; + const ValueTp v(42); + cc->expect(); + assert(c.insert(v).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const ValueTp v2(42); + assert(c.insert(v2).second == false); + } + } + { + PRINT("Testing C::insert(value_type&)"); + Container c; + ValueTp v(42); + cc->expect(); + assert(c.insert(v).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + ValueTp v2(42); + assert(c.insert(v2).second == false); + } + } + { + PRINT("Testing C::insert(value_type&&)"); + Container c; + ValueTp v(42); + cc->expect(); + assert(c.insert(std::move(v)).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + ValueTp v2(42); + assert(c.insert(std::move(v2)).second == false); + } + } + { + PRINT("Testing C::insert(const value_type&&)"); + Container c; + const ValueTp v(42); + cc->expect(); + assert(c.insert(std::move(v)).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const ValueTp v2(42); + assert(c.insert(std::move(v2)).second == false); + } + } + { + PRINT("Testing C::insert(std::initializer_list)"); + Container c; + std::initializer_list il = { ValueTp(1), ValueTp(2) }; + cc->expect(2); + c.insert(il); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + c.insert(il); + } + } + { + PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type const&"); + Container c; + const ValueTp ValueList[] = { ValueTp(1), ValueTp(2), ValueTp(3) }; + cc->expect(3); + c.insert(std::begin(ValueList), std::end(ValueList)); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + c.insert(std::begin(ValueList), std::end(ValueList)); + } + } + { + PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type&&"); + Container c; + ValueTp ValueList[] = { ValueTp(1), ValueTp(2) , ValueTp(3) }; + cc->expect(3); + c.insert(std::move_iterator(std::begin(ValueList)), + std::move_iterator(std::end(ValueList))); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + ValueTp ValueList2[] = { ValueTp(1), ValueTp(2) , ValueTp(3) }; + c.insert(std::move_iterator(std::begin(ValueList2)), + std::move_iterator(std::end(ValueList2))); + } + } + { + PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type&"); + Container c; + ValueTp ValueList[] = { ValueTp(1), ValueTp(2) , ValueTp(3) }; + cc->expect(3); + c.insert(std::begin(ValueList), std::end(ValueList)); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + c.insert(std::begin(ValueList), std::end(ValueList)); + } + } +} + + +template +void testContainerEmplace() +{ + typedef typename Container::value_type ValueTp; + typedef Container C; + typedef std::pair R; + ConstructController* cc = getConstructController(); + cc->reset(); + { + PRINT("Testing C::emplace(const value_type&)"); + Container c; + const ValueTp v(42); + cc->expect(); + assert(c.emplace(v).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const ValueTp v2(42); + assert(c.emplace(v2).second == false); + } + } + { + PRINT("Testing C::emplace(value_type&)"); + Container c; + ValueTp v(42); + cc->expect(); + assert(c.emplace(v).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + ValueTp v2(42); + assert(c.emplace(v2).second == false); + } + } + { + PRINT("Testing C::emplace(value_type&&)"); + Container c; + ValueTp v(42); + cc->expect(); + assert(c.emplace(std::move(v)).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + ValueTp v2(42); + assert(c.emplace(std::move(v2)).second == false); + } + } + { + PRINT("Testing C::emplace(const value_type&&)"); + Container c; + const ValueTp v(42); + cc->expect(); + assert(c.emplace(std::move(v)).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const ValueTp v2(42); + assert(c.emplace(std::move(v2)).second == false); + } + } +} + + +template +void testContainerEmplaceHint() +{ + typedef typename Container::value_type ValueTp; + + typedef Container C; + typedef typename C::iterator It; + ConstructController* cc = getConstructController(); + cc->reset(); + { + PRINT("Testing C::emplace_hint(p, const value_type&)"); + Container c; + const ValueTp v(42); + cc->expect(); + It ret = c.emplace_hint(c.end(), v); + assert(ret != c.end()); + assert(c.size() == 1); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const ValueTp v2(42); + It ret2 = c.emplace_hint(c.begin(), v2); + assert(&(*ret2) == &(*ret)); + assert(c.size() == 1); + } + } + { + PRINT("Testing C::emplace_hint(p, value_type&)"); + Container c; + ValueTp v(42); + cc->expect(); + It ret = c.emplace_hint(c.end(), v); + assert(ret != c.end()); + assert(c.size() == 1); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + ValueTp v2(42); + It ret2 = c.emplace_hint(c.begin(), v2); + assert(&(*ret2) == &(*ret)); + assert(c.size() == 1); + } + } + { + PRINT("Testing C::emplace_hint(p, value_type&&)"); + Container c; + ValueTp v(42); + cc->expect(); + It ret = c.emplace_hint(c.end(), std::move(v)); + assert(ret != c.end()); + assert(c.size() == 1); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + ValueTp v2(42); + It ret2 = c.emplace_hint(c.begin(), std::move(v2)); + assert(&(*ret2) == &(*ret)); + assert(c.size() == 1); + } + } + { + PRINT("Testing C::emplace_hint(p, const value_type&&)"); + Container c; + const ValueTp v(42); + cc->expect(); + It ret = c.emplace_hint(c.end(), std::move(v)); + assert(ret != c.end()); + assert(c.size() == 1); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const ValueTp v2(42); + It ret2 = c.emplace_hint(c.begin(), std::move(v2)); + assert(&(*ret2) == &(*ret)); + assert(c.size() == 1); + } + } +} + + +int main() +{ + testContainerInsert >(); + testContainerEmplace >(); + testContainerEmplaceHint >(); +}