Skip to content
This repository was archived by the owner on Mar 22, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 30 additions & 1 deletion include/libpmemobj++/container/array.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: BSD-3-Clause
/* Copyright 2018-2020, Intel Corporation */
/* Copyright 2018-2021, Intel Corporation */

/**
* @file
Expand All @@ -11,6 +11,7 @@

#include <algorithm>
#include <functional>
#include <initializer_list>

#include <libpmemobj++/container/detail/contiguous_iterator.hpp>
#include <libpmemobj++/detail/common.hpp>
Expand Down Expand Up @@ -41,6 +42,15 @@ namespace obj
*
* When a non-const iterator is returned it adds part of the array
* to a transaction while traversing.
*
* @note According to changes in C++ standard, pmem::obj::array is not an
* aggregate since C++20.
*
* @note Since C++20 pmem::obj::array cannot be initialized via constructor for
* types with deleted copy constructor. This may change in the future.
*
* @note Since C++20 pmem::obj::array for const types can be initialized only
* via default constructor. This may change in the future.
*/
template <typename T, std::size_t N>
struct array {
Expand Down Expand Up @@ -98,6 +108,25 @@ struct array {
*/
array(array &&) = default;

#if __cplusplus > 201703L
/**
* Constructor taking std::initializer_list.
*
* It provides similar initialization semantics for
* C++20 (where pmem::obj::array is no longer an aggregate).
*/
array(std::initializer_list<T> list)
{
if constexpr (N > 0) {
size_t i = 0;
for (auto &v : list) {
(*this)[i] = v;
i++;
}
}
}
#endif /* __cplusplus */

/**
* Copy assignment operator - perform assignment from other
* pmem::obj::array.
Expand Down
4 changes: 4 additions & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,10 @@ if(TEST_ARRAY)
add_test_generic(NAME array_slice_pmreorder CASE 0 TRACERS none SCRIPT array/array_slice_pmreorder_0.cmake)
add_test_generic(NAME array_slice_pmreorder CASE 1 TRACERS none SCRIPT array/array_slice_pmreorder_1.cmake)
endif()
if(CXX_STANDARD GREATER 14)
build_test(array_is_aggregate array/array_is_aggregate.cpp)
add_test_generic(NAME array_is_aggregate TRACERS none)
endif()
endif()
################################################################################
###################################### VECTOR ##################################
Expand Down
23 changes: 23 additions & 0 deletions tests/array/array_is_aggregate.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// SPDX-License-Identifier: BSD-3-Clause
/* Copyright 2021, Intel Corporation */

#include "unittest.hpp"

#include <libpmemobj++/container/array.hpp>

/* Test which checks if array behave in the same way as any structure with
* defaulted constructor - according to used c++ standard */
struct struct_with_defaulted_constructor {
struct_with_defaulted_constructor() = default;
};

int
main()
{
bool array_is_aggregate =
std::is_aggregate<pmem::obj::array<int, 1>>::value;
bool cpp_standard_support =
std::is_aggregate<struct_with_defaulted_constructor>::value;

UT_ASSERTeq(array_is_aggregate, cpp_standard_support);
}
4 changes: 2 additions & 2 deletions tests/common/helper_classes.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: BSD-3-Clause
/* Copyright 2019, Intel Corporation */
/* Copyright 2019-2021, Intel Corporation */

/**
* Helper classes that represent C++ concepts
Expand Down Expand Up @@ -357,7 +357,7 @@ struct CompoundType {
}

bool
operator==(const CompoundType &rhs)
operator==(const CompoundType &rhs) const
{
return counter == rhs.counter;
}
Expand Down
19 changes: 12 additions & 7 deletions tests/external/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -101,17 +101,22 @@ if (TEST_ARRAY)
build_test(array_swap_2 libcxx/array/array.swap/swap.pass.cpp)
add_test_generic(NAME array_swap_2 TRACERS none)

build_test(array_get_const_rv libcxx/array/array.tuple/get_const_rv.pass.cpp)
add_test_generic(NAME array_get_const_rv TRACERS none)

build_test(array_get_const libcxx/array/array.tuple/get_const.pass.cpp)
add_test_generic(NAME array_get_const TRACERS none)

build_test(array_get_rv libcxx/array/array.tuple/get_rv.pass.cpp)
add_test_generic(NAME array_get_rv TRACERS none)
if(CXX_STANDARD LESS 20)
build_test(array_get_const_rv libcxx/array/array.tuple/get_const_rv.pass.cpp)
add_test_generic(NAME array_get_const_rv TRACERS none)

build_test(array_get_rv libcxx/array/array.tuple/get_rv.pass.cpp)
add_test_generic(NAME array_get_rv TRACERS none)

build_test(array_get libcxx/array/array.tuple/get.pass.cpp)
add_test_generic(NAME array_get TRACERS none)
build_test(array_get libcxx/array/array.tuple/get.pass.cpp)
add_test_generic(NAME array_get TRACERS none)

build_test(array_cons_implicit_copy_const libcxx/array/array.cons/implicit_copy_const.pass.cpp)
add_test_generic(NAME array_cons_implicit_copy_const TRACERS none)
endif()

add_test_expect_failure(array_get libcxx/array/array.tuple/get.fail.cpp)

Expand Down
57 changes: 1 addition & 56 deletions tests/external/libcxx/array/array.cons/implicit_copy.pass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,20 +47,6 @@ struct Testcase1 {
};

struct Testcase2 {
typedef double T;
typedef pmem::obj::array<const T, 3> C;
C c = {{1.1, 2.2, 3.3}};
C c2 = c;

void
run()
{
((void)c2);
static_assert(std::is_copy_constructible<C>::value, "");
}
};

struct Testcase3 {
typedef double T;
typedef pmem::obj::array<T, 0> C;
C c = {{}};
Expand All @@ -74,23 +60,7 @@ struct Testcase3 {
}
};

struct Testcase4 {
// const arrays of size 0 should disable the implicit copy
// assignment operator.
typedef double T;
typedef pmem::obj::array<const T, 0> C;
C c = {{}};
C c2 = c;

void
run()
{
((void)c2);
static_assert(std::is_copy_constructible<C>::value, "");
}
};

struct Testcase5 {
struct Testcase3 {
typedef NoDefault T;
typedef pmem::obj::array<T, 0> C;
C c = {{}};
Expand All @@ -105,26 +75,10 @@ struct Testcase5 {
}
};

struct Testcase6 {
typedef NoDefault T;
typedef pmem::obj::array<const T, 0> C;
C c = {{}};
C c2 = c;
void
run()
{
((void)c2);
static_assert(std::is_copy_constructible<C>::value, "");
}
};

struct root {
pmem::obj::persistent_ptr<Testcase1> r1;
pmem::obj::persistent_ptr<Testcase2> r2;
pmem::obj::persistent_ptr<Testcase3> r3;
pmem::obj::persistent_ptr<Testcase4> r4;
pmem::obj::persistent_ptr<Testcase5> r5;
pmem::obj::persistent_ptr<Testcase6> r6;
};

void
Expand All @@ -138,20 +92,11 @@ run(pmem::obj::pool<root> &pop)
pmem::obj::make_persistent<Testcase2>();
pop.root()->r3 =
pmem::obj::make_persistent<Testcase3>();
pop.root()->r4 =
pmem::obj::make_persistent<Testcase4>();
pop.root()->r5 =
pmem::obj::make_persistent<Testcase5>();
pop.root()->r6 =
pmem::obj::make_persistent<Testcase6>();
});

pop.root()->r1->run();
pop.root()->r2->run();
pop.root()->r3->run();
pop.root()->r4->run();
pop.root()->r5->run();
pop.root()->r6->run();
} catch (...) {
UT_ASSERT(0);
}
Expand Down
125 changes: 125 additions & 0 deletions tests/external/libcxx/array/array.cons/implicit_copy_const.pass.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
//===----------------------------------------------------------------------===//
//
// 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.
//
//===----------------------------------------------------------------------===//
//
// Copyright 2018-2021, Intel Corporation
//
// Modified to test pmem::obj containers
//

#include "unittest.hpp"

#include <libpmemobj++/container/array.hpp>
#include <libpmemobj++/make_persistent.hpp>
#include <libpmemobj++/persistent_ptr.hpp>
#include <libpmemobj++/pool.hpp>
#include <libpmemobj++/transaction.hpp>

struct NoDefault {
NoDefault(int)
{
}
};

struct Testcase1 {
typedef double T;
typedef pmem::obj::array<const T, 3> C;
C c = {{1.1, 2.2, 3.3}};
C c2 = c;

void
run()
{
(void)c2;
static_assert(std::is_copy_constructible<C>::value, "");
}
};

struct Testcase2 {
// const arrays of size 0 should disable the implicit copy
// assignment operator.
typedef double T;
typedef pmem::obj::array<const T, 0> C;
C c = {{}};
C c2 = c;

void
run()
{
(void)c2;
static_assert(std::is_copy_constructible<C>::value, "");
}
};

struct Testcase3 {
typedef NoDefault T;
typedef pmem::obj::array<const T, 0> C;
C c = {{}};
C c2 = c;
void
run()
{
(void)c2;
static_assert(std::is_copy_constructible<C>::value, "");
}
};

struct root {
pmem::obj::persistent_ptr<Testcase1> r1;
pmem::obj::persistent_ptr<Testcase2> r2;
pmem::obj::persistent_ptr<Testcase3> r3;
};

void
run(pmem::obj::pool<root> &pop)
{
try {
pmem::obj::transaction::run(pop, [&] {
pop.root()->r1 =
pmem::obj::make_persistent<Testcase1>();
pop.root()->r2 =
pmem::obj::make_persistent<Testcase2>();
pop.root()->r3 =
pmem::obj::make_persistent<Testcase3>();
});

pop.root()->r1->run();
pop.root()->r2->run();
pop.root()->r3->run();
} catch (...) {
UT_ASSERT(0);
}
}

static void
test(int argc, char *argv[])
{
if (argc != 2)
UT_FATAL("usage: %s file-name", argv[0]);

const char *path = argv[1];

pmem::obj::pool<root> pop;
try {
pop = pmem::obj::pool<root>::create(path, "implicit_copy.pass",
PMEMOBJ_MIN_POOL,
S_IWUSR | S_IRUSR);
} catch (...) {
UT_FATAL("!pmemobj_create: %s", path);
}

run(pop);

pop.close();
}

int
main(int argc, char *argv[])
{
return run_test([&] { test(argc, argv); });
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,13 @@ struct Testcase2 {
struct Testcase3 {
typedef double T;
typedef pmem::obj::array<T, 3> C;
#if __cplusplus > 201703L
C c = {1};
#else
/* This syntax causes warning: braces around scalar initializer
* on C++20*/
C c = {{1}};

#endif
void
run()
{
Expand Down
3 changes: 2 additions & 1 deletion utils/docker/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ if [[ -z "${COMMAND}" ]]; then
;;
release)
builds=(tests_gcc_release_cpp17_no_valgrind
tests_clang_release_cpp11_no_valgrind)
tests_clang_release_cpp11_no_valgrind
tests_clang_release_cpp20_no_valgrind)
COMMAND="./run-build.sh ${builds[@]}";
;;
valgrind)
Expand Down
9 changes: 9 additions & 0 deletions utils/docker/prepare-for-build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,12 @@ if [ "${CI_RUN}" == "YES" ]; then
sudo_password chmod 0777 ${TEST_DIR}
sudo_password mount -o size=2G -t tmpfs none ${TEST_DIR}
fi || true

echo "CMake version:"
cmake --version

# assign CMake's version to variable(s) - a single number representation for easier comparison
CMAKE_VERSION=$(cmake --version | head -n1 | grep -P -o "\d+\.\d+")
CMAKE_VERSION_MAJOR=$(echo ${CMAKE_VERSION} | cut -d. -f1)
CMAKE_VERSION_MINOR=$(echo ${CMAKE_VERSION} | cut -d. -f2)
CMAKE_VERSION_NUMBER=${CMAKE_VERSION_MAJOR}${CMAKE_VERSION_MINOR}
Loading