From 0fa118a9da6786a0aaf81e309d8c3b38bc5f61dd Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Mon, 16 Dec 2019 17:00:10 -0500 Subject: [PATCH] Add default initialization to compressed_pair. This change introduces the __default_init_tag to memory, and a corresponding element constructor to allow for default initialization of either of the pair values. This is useful for classes such as std::string where most (all) constructors explicitly initialize the values in the constructor. Patch by Martijn Vels (mvels@google.com) Reviewed as https://reviews.llvm.org/D70617 --- libcxx/include/memory | 7 +++ .../compressed_pair/compressed_pair.pass.cpp | 51 ++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 libcxx/test/libcxx/memory/compressed_pair/compressed_pair.pass.cpp diff --git a/libcxx/include/memory b/libcxx/include/memory index 1723b30..45e032ae 100644 --- a/libcxx/include/memory +++ b/libcxx/include/memory @@ -2178,6 +2178,9 @@ public: }; #endif +// Tag used to default initialize one or both of the pair's elements. +struct __default_init_tag {}; + template ::value && !__libcpp_is_final<_Tp>::value> @@ -2188,6 +2191,8 @@ struct __compressed_pair_elem { #ifndef _LIBCPP_CXX03_LANG _LIBCPP_INLINE_VISIBILITY constexpr __compressed_pair_elem() : __value_() {} + _LIBCPP_INLINE_VISIBILITY constexpr + __compressed_pair_elem(__default_init_tag) {} template ::type>::value @@ -2207,6 +2212,8 @@ struct __compressed_pair_elem { #else _LIBCPP_INLINE_VISIBILITY __compressed_pair_elem() : __value_() {} _LIBCPP_INLINE_VISIBILITY + __compressed_pair_elem(__default_init_tag) {} + _LIBCPP_INLINE_VISIBILITY __compressed_pair_elem(_ParamT __p) : __value_(std::forward<_ParamT>(__p)) {} #endif diff --git a/libcxx/test/libcxx/memory/compressed_pair/compressed_pair.pass.cpp b/libcxx/test/libcxx/memory/compressed_pair/compressed_pair.pass.cpp new file mode 100644 index 0000000..53acd8f --- /dev/null +++ b/libcxx/test/libcxx/memory/compressed_pair/compressed_pair.pass.cpp @@ -0,0 +1,51 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include +#include + +#include "test_macros.h" + +typedef std::__compressed_pair IntPair; + +void test_constructor() { + IntPair value; + assert(value.first() == 0); + assert(value.second() == 0); + + value.first() = 1; + value.second() = 2; + new (&value) IntPair; + assert(value.first() == 0); + assert(value.second() == 0); +} + +void test_constructor_default_init() { + IntPair value; + value.first() = 1; + value.second() = 2; + + new (&value) IntPair(std::__default_init_tag(), 3); + assert(value.first() == 1); + assert(value.second() == 3); + + new (&value) IntPair(4, std::__default_init_tag()); + assert(value.first() == 4); + assert(value.second() == 3); + + new (&value) IntPair(std::__default_init_tag(), std::__default_init_tag()); + assert(value.first() == 4); + assert(value.second() == 3); +} + +int main(int, char**) +{ + test_constructor(); + test_constructor_default_init(); + return 0; +} -- 2.7.4