[mxtl] Define initializer_list<T>

This is a bit tricky because the compiler hardcodes a dependency on
std::initializer_list<T>.  We use the C++ standard library definition
when available, otherwise we define our own.

Change-Id: I65a67b80ffe607b2769550bbe92a668f3bb81a27
Esse commit está contido em:
Jeff Brown
2017-08-23 21:36:24 -07:00
commit f0ce80d2c5
6 arquivos alterados com 121 adições e 2 exclusões
+2 -2
Ver Arquivo
@@ -311,10 +311,10 @@ GENERATED :=
GLOBAL_DEFINES :=
# anything added to KERNEL_DEFINES will be put into $(BUILDDIR)/config-kernel.h
KERNEL_DEFINES := LK=1 _KERNEL=1
KERNEL_DEFINES := LK=1 _KERNEL=1 MAGENTA_TOOLCHAIN=1
# anything added to USER_DEFINES will be put into $(BUILDDIR)/config-user.h
USER_DEFINES :=
USER_DEFINES := MAGENTA_TOOLCHAIN=1
# anything added to HOST_DEFINES will be put into $(BUILDDIR)/config-host.h
HOST_DEFINES :=
+50
Ver Arquivo
@@ -0,0 +1,50 @@
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Provides std::initializer_list<T> on behalf of the Magenta toolchain
// when compiling without the C++ standard library.
//
#pragma once
#ifndef MAGENTA_TOOLCHAIN
#error "This header must only be included when using the magenta toolchain."
#endif
// This implementation is known to be compatible with our GCC and Clang toolchains.
#if defined(__GNUC__) || defined(__clang__)
#include <stddef.h>
namespace std {
template <typename T>
class initializer_list {
public:
using value_type = T;
using reference = const T&;
using const_reference = const T&;
using size_type = size_t;
using iterator = const T*;
using const_iterator = const T*;
constexpr initializer_list()
: items_(nullptr), size_(0u) {}
constexpr size_t size() const { return size_; }
constexpr const T* begin() const { return items_; }
constexpr const T* end() const { return items_ + size_; }
private:
constexpr initializer_list(const T* items, size_t size)
: items_(items), size_(size) {}
const T* items_;
size_t size_;
};
} // namespace std
#else
#error "std::initializer_list<T> not supported by this toolchain"
#endif // defined(__GNUC__) || defined(__clang__)
+1
Ver Arquivo
@@ -19,6 +19,7 @@ source_set("mxtl") {
"include/mxtl/canary.h",
"include/mxtl/deleter.h",
"include/mxtl/function.h",
"include/mxtl/initializer_list.h",
"include/mxtl/intrusive_container_utils.h",
"include/mxtl/intrusive_double_list.h",
"include/mxtl/intrusive_hash_table.h",
@@ -0,0 +1,26 @@
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Provides mxtl::initializer_list<T>.
// Unfortunately the C++ compiler hardcodes a dependency on std::initializer_list<T>.
// We use the C++ standard library definition when available, otherwise we
// use the one offered by the Magenta toolchain.
//
#pragma once
#ifdef MAGENTA_TOOLCHAIN
// Use the implementation supplied by the Magenta toolchain when we are
// compiling without the C++ standard library.
#include <magenta/initializer_list.h>
#else
// Use the implementation supplied by the C++ standard library.
#include <initializer_list>
#endif // MAGENTA_TOOLCHAIN
// Expose std::initializer_list<T> as mxtl::initializer_list<T>.
namespace mxtl {
using std::initializer_list;
}
+41
Ver Arquivo
@@ -0,0 +1,41 @@
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <mxtl/initializer_list.h>
#include <unittest/unittest.h>
namespace {
void ExpectListContents(size_t expected_size, mxtl::initializer_list<int> list) {
EXPECT_EQ(expected_size, list.size());
size_t index = 0;
for (const int *it = list.begin(); it != list.end(); ++it, ++index) {
EXPECT_EQ(static_cast<int>(index), *it);
}
EXPECT_EQ(expected_size, index);
}
bool empty_test() {
BEGIN_TEST;
ExpectListContents(0u, {});
END_TEST;
}
bool non_empty_test() {
BEGIN_TEST;
ExpectListContents(6u, {0, 1, 2, 3, 4, 5});
END_TEST;
}
} // namespace
BEGIN_TEST_CASE(initializer_list_tests)
RUN_TEST(empty_test)
RUN_TEST(non_empty_test)
END_TEST_CASE(initializer_list_tests)
+1
Ver Arquivo
@@ -11,6 +11,7 @@ mxtl_common_tests := \
$(LOCAL_DIR)/auto_call_tests.cpp \
$(LOCAL_DIR)/forward_tests.cpp \
$(LOCAL_DIR)/function_tests.cpp \
$(LOCAL_DIR)/initializer_list_tests.cpp \
$(LOCAL_DIR)/intrusive_container_tests.cpp \
$(LOCAL_DIR)/intrusive_doubly_linked_list_tests.cpp \
$(LOCAL_DIR)/intrusive_hash_table_dll_tests.cpp \