FTL: Standardize style
Adopt STL-flavored Google style for internal and libbase consistency.
Add README.
Bug: 160012986
Test: ftl_test
Change-Id: I1056f6fa890d68717386d634c398bb2faa46775c
diff --git a/include/ftl/ArrayTraits.h b/include/ftl/array_traits.h
similarity index 90%
rename from include/ftl/ArrayTraits.h
rename to include/ftl/array_traits.h
index ff685c5..011034f 100644
--- a/include/ftl/ArrayTraits.h
+++ b/include/ftl/array_traits.h
@@ -28,8 +28,8 @@
template <typename T>
struct ArrayTraits {
using value_type = T;
- using size_type = size_t;
- using difference_type = ptrdiff_t;
+ using size_type = std::size_t;
+ using difference_type = std::ptrdiff_t;
using pointer = value_type*;
using reference = value_type&;
@@ -99,34 +99,34 @@
// Mixin to define comparison operators for an array-like template.
// TODO: Replace with operator<=> in C++20.
-template <template <typename, size_t> class Array>
+template <template <typename, std::size_t> class Array>
struct ArrayComparators {
- template <typename T, size_t N, size_t M>
+ template <typename T, std::size_t N, std::size_t M>
friend bool operator==(const Array<T, N>& lhs, const Array<T, M>& rhs) {
return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin());
}
- template <typename T, size_t N, size_t M>
+ template <typename T, std::size_t N, std::size_t M>
friend bool operator<(const Array<T, N>& lhs, const Array<T, M>& rhs) {
return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
}
- template <typename T, size_t N, size_t M>
+ template <typename T, std::size_t N, std::size_t M>
friend bool operator>(const Array<T, N>& lhs, const Array<T, M>& rhs) {
return rhs < lhs;
}
- template <typename T, size_t N, size_t M>
+ template <typename T, std::size_t N, std::size_t M>
friend bool operator!=(const Array<T, N>& lhs, const Array<T, M>& rhs) {
return !(lhs == rhs);
}
- template <typename T, size_t N, size_t M>
+ template <typename T, std::size_t N, std::size_t M>
friend bool operator>=(const Array<T, N>& lhs, const Array<T, M>& rhs) {
return !(lhs < rhs);
}
- template <typename T, size_t N, size_t M>
+ template <typename T, std::size_t N, std::size_t M>
friend bool operator<=(const Array<T, N>& lhs, const Array<T, M>& rhs) {
return !(lhs > rhs);
}
diff --git a/include/ftl/InitializerList.h b/include/ftl/initializer_list.h
similarity index 95%
rename from include/ftl/InitializerList.h
rename to include/ftl/initializer_list.h
index bb99280..62f63b7 100644
--- a/include/ftl/InitializerList.h
+++ b/include/ftl/initializer_list.h
@@ -27,7 +27,7 @@
// first S0 arguments, the second element is initialized with the next S1 arguments, and so
// on. The list of Types (T0, ..., TM) is flattened, so M is equal to the sum of the Sizes.
//
-// The InitializerList is created using ftl::init::list, and is consumed by constructors of
+// An InitializerList is created using ftl::init::list, and is consumed by constructors of
// containers. The function call operator is overloaded such that arguments are accumulated
// in a tuple with each successive call. For instance, the following calls initialize three
// strings using different constructors, i.e. string literal, default, and count/character:
@@ -49,7 +49,7 @@
template <typename T, typename Sizes = std::index_sequence<>, typename... Types>
struct InitializerList;
-template <typename T, size_t... Sizes, typename... Types>
+template <typename T, std::size_t... Sizes, typename... Types>
struct InitializerList<T, std::index_sequence<Sizes...>, Types...> {
// Creates a superset InitializerList by appending the number of arguments to Sizes, and
// expanding Types with forwarding references for each argument.
@@ -72,7 +72,7 @@
// Shorthand for key-value pairs that assigns the first argument to the key, and the rest to the
// value. The specialization is on KeyValue rather than std::pair, so that ftl::init::list works
// with the latter.
-template <typename K, typename V, size_t... Sizes, typename... Types>
+template <typename K, typename V, std::size_t... Sizes, typename... Types>
struct InitializerList<KeyValue<K, V>, std::index_sequence<Sizes...>, Types...> {
// Accumulate the three arguments to std::pair's piecewise constructor.
template <typename... Args>
diff --git a/include/ftl/SmallMap.h b/include/ftl/small_map.h
similarity index 87%
rename from include/ftl/SmallMap.h
rename to include/ftl/small_map.h
index 87ae99c..d058369 100644
--- a/include/ftl/SmallMap.h
+++ b/include/ftl/small_map.h
@@ -16,8 +16,8 @@
#pragma once
-#include <ftl/InitializerList.h>
-#include <ftl/SmallVector.h>
+#include <ftl/initializer_list.h>
+#include <ftl/small_vector.h>
#include <functional>
#include <optional>
@@ -54,7 +54,7 @@
//
// assert(map == SmallMap(ftl::init::map(-1, "xyz")(42, "???")(123, "abc")));
//
-template <typename K, typename V, size_t N>
+template <typename K, typename V, std::size_t N>
class SmallMap final {
using Map = SmallVector<std::pair<const K, V>, N>;
@@ -92,26 +92,26 @@
// ftl::SmallMap map = ftl::init::map(0, 'a')(1, 'b')(2, 'c');
// static_assert(std::is_same_v<decltype(map), ftl::SmallMap<int, char, 3>>);
//
- template <typename U, size_t... Sizes, typename... Types>
- SmallMap(InitializerList<U, std::index_sequence<Sizes...>, Types...>&& init)
- : mMap(std::move(init)) {
+ template <typename U, std::size_t... Sizes, typename... Types>
+ SmallMap(InitializerList<U, std::index_sequence<Sizes...>, Types...>&& list)
+ : map_(std::move(list)) {
// TODO: Enforce unique keys.
}
- size_type max_size() const { return mMap.max_size(); }
- size_type size() const { return mMap.size(); }
- bool empty() const { return mMap.empty(); }
+ size_type max_size() const { return map_.max_size(); }
+ size_type size() const { return map_.size(); }
+ bool empty() const { return map_.empty(); }
// Returns whether the map is backed by static or dynamic storage.
- bool dynamic() const { return mMap.dynamic(); }
+ bool dynamic() const { return map_.dynamic(); }
- iterator begin() { return mMap.begin(); }
+ iterator begin() { return map_.begin(); }
const_iterator begin() const { return cbegin(); }
- const_iterator cbegin() const { return mMap.cbegin(); }
+ const_iterator cbegin() const { return map_.cbegin(); }
- iterator end() { return mMap.end(); }
+ iterator end() { return map_.end(); }
const_iterator end() const { return cend(); }
- const_iterator cend() const { return mMap.cend(); }
+ const_iterator cend() const { return map_.cend(); }
// Returns whether a mapping exists for the given key.
bool contains(const key_type& key) const {
@@ -173,16 +173,16 @@
}
private:
- Map mMap;
+ Map map_;
};
// Deduction guide for in-place constructor.
-template <typename K, typename V, size_t... Sizes, typename... Types>
+template <typename K, typename V, std::size_t... Sizes, typename... Types>
SmallMap(InitializerList<KeyValue<K, V>, std::index_sequence<Sizes...>, Types...>&&)
-> SmallMap<K, V, sizeof...(Sizes)>;
// Returns whether the key-value pairs of two maps are equal.
-template <typename K, typename V, size_t N, typename Q, typename W, size_t M>
+template <typename K, typename V, std::size_t N, typename Q, typename W, std::size_t M>
bool operator==(const SmallMap<K, V, N>& lhs, const SmallMap<Q, W, M>& rhs) {
if (lhs.size() != rhs.size()) return false;
@@ -197,7 +197,7 @@
}
// TODO: Remove in C++20.
-template <typename K, typename V, size_t N, typename Q, typename W, size_t M>
+template <typename K, typename V, std::size_t N, typename Q, typename W, std::size_t M>
inline bool operator!=(const SmallMap<K, V, N>& lhs, const SmallMap<Q, W, M>& rhs) {
return !(lhs == rhs);
}
diff --git a/include/ftl/SmallVector.h b/include/ftl/small_vector.h
similarity index 80%
rename from include/ftl/SmallVector.h
rename to include/ftl/small_vector.h
index 2f05a9b..a8686ba 100644
--- a/include/ftl/SmallVector.h
+++ b/include/ftl/small_vector.h
@@ -16,8 +16,8 @@
#pragma once
-#include <ftl/ArrayTraits.h>
-#include <ftl/StaticVector.h>
+#include <ftl/array_traits.h>
+#include <ftl/static_vector.h>
#include <algorithm>
#include <iterator>
@@ -29,7 +29,7 @@
namespace android::ftl {
template <typename>
-struct IsSmallVector;
+struct is_small_vector;
// ftl::StaticVector that promotes to std::vector when full. SmallVector is a drop-in replacement
// for std::vector with statically allocated storage for N elements, whose goal is to improve run
@@ -74,7 +74,7 @@
// assert(strings[1] == "123");
// assert(strings[2] == "???");
//
-template <typename T, size_t N>
+template <typename T, std::size_t N>
class SmallVector final : ArrayTraits<T>, ArrayComparators<SmallVector> {
using Static = StaticVector<T, N>;
using Dynamic = SmallVector<T, 0>;
@@ -103,25 +103,25 @@
// Constructs at most N elements. See StaticVector for underlying constructors.
template <typename Arg, typename... Args,
- typename = std::enable_if_t<!IsSmallVector<remove_cvref_t<Arg>>{}>>
+ typename = std::enable_if_t<!is_small_vector<remove_cvref_t<Arg>>{}>>
SmallVector(Arg&& arg, Args&&... args)
- : mVector(std::in_place_type<Static>, std::forward<Arg>(arg),
+ : vector_(std::in_place_type<Static>, std::forward<Arg>(arg),
std::forward<Args>(args)...) {}
// Copies at most N elements from a smaller convertible vector.
- template <typename U, size_t M, typename = std::enable_if_t<M <= N>>
+ template <typename U, std::size_t M, typename = std::enable_if_t<M <= N>>
SmallVector(const SmallVector<U, M>& other)
- : SmallVector(IteratorRange, other.begin(), other.end()) {}
+ : SmallVector(kIteratorRange, other.begin(), other.end()) {}
- void swap(SmallVector& other) { mVector.swap(other.mVector); }
+ void swap(SmallVector& other) { vector_.swap(other.vector_); }
// Returns whether the vector is backed by static or dynamic storage.
- bool dynamic() const { return std::holds_alternative<Dynamic>(mVector); }
+ bool dynamic() const { return std::holds_alternative<Dynamic>(vector_); }
// Avoid std::visit as it generates a dispatch table.
#define DISPATCH(T, F, ...) \
T F() __VA_ARGS__ { \
- return dynamic() ? std::get<Dynamic>(mVector).F() : std::get<Static>(mVector).F(); \
+ return dynamic() ? std::get<Dynamic>(vector_).F() : std::get<Static>(vector_).F(); \
}
DISPATCH(size_type, max_size, const)
@@ -157,7 +157,7 @@
#undef DISPATCH
reference operator[](size_type i) {
- return dynamic() ? std::get<Dynamic>(mVector)[i] : std::get<Static>(mVector)[i];
+ return dynamic() ? std::get<Dynamic>(vector_)[i] : std::get<Static>(vector_)[i];
}
const_reference operator[](size_type i) const { return const_cast<SmallVector&>(*this)[i]; }
@@ -175,9 +175,9 @@
template <typename... Args>
reference replace(const_iterator it, Args&&... args) {
if (dynamic()) {
- return std::get<Dynamic>(mVector).replace(it, std::forward<Args>(args)...);
+ return std::get<Dynamic>(vector_).replace(it, std::forward<Args>(args)...);
} else {
- return std::get<Static>(mVector).replace(it, std::forward<Args>(args)...);
+ return std::get<Static>(vector_).replace(it, std::forward<Args>(args)...);
}
}
@@ -188,9 +188,9 @@
//
template <typename... Args>
reference emplace_back(Args&&... args) {
- constexpr auto insertStatic = &Static::template emplace_back<Args...>;
- constexpr auto insertDynamic = &Dynamic::template emplace_back<Args...>;
- return *insert<insertStatic, insertDynamic>(std::forward<Args>(args)...);
+ constexpr auto kInsertStatic = &Static::template emplace_back<Args...>;
+ constexpr auto kInsertDynamic = &Dynamic::template emplace_back<Args...>;
+ return *insert<kInsertStatic, kInsertDynamic>(std::forward<Args>(args)...);
}
// Appends an element.
@@ -199,19 +199,19 @@
// Otherwise, only the end() iterator is invalidated.
//
void push_back(const value_type& v) {
- constexpr auto insertStatic =
+ constexpr auto kInsertStatic =
static_cast<bool (Static::*)(const value_type&)>(&Static::push_back);
- constexpr auto insertDynamic =
+ constexpr auto kInsertDynamic =
static_cast<bool (Dynamic::*)(const value_type&)>(&Dynamic::push_back);
- insert<insertStatic, insertDynamic>(v);
+ insert<kInsertStatic, kInsertDynamic>(v);
}
void push_back(value_type&& v) {
- constexpr auto insertStatic =
+ constexpr auto kInsertStatic =
static_cast<bool (Static::*)(value_type&&)>(&Static::push_back);
- constexpr auto insertDynamic =
+ constexpr auto kInsertDynamic =
static_cast<bool (Dynamic::*)(value_type&&)>(&Dynamic::push_back);
- insert<insertStatic, insertDynamic>(std::move(v));
+ insert<kInsertStatic, kInsertDynamic>(std::move(v));
}
// Removes the last element. The vector must not be empty, or the call is erroneous.
@@ -220,9 +220,9 @@
//
void pop_back() {
if (dynamic()) {
- std::get<Dynamic>(mVector).pop_back();
+ std::get<Dynamic>(vector_).pop_back();
} else {
- std::get<Static>(mVector).pop_back();
+ std::get<Static>(vector_).pop_back();
}
}
@@ -233,39 +233,39 @@
//
void unstable_erase(iterator it) {
if (dynamic()) {
- std::get<Dynamic>(mVector).unstable_erase(it);
+ std::get<Dynamic>(vector_).unstable_erase(it);
} else {
- std::get<Static>(mVector).unstable_erase(it);
+ std::get<Static>(vector_).unstable_erase(it);
}
}
private:
- template <auto insertStatic, auto insertDynamic, typename... Args>
+ template <auto InsertStatic, auto InsertDynamic, typename... Args>
auto insert(Args&&... args) {
- if (Dynamic* const vector = std::get_if<Dynamic>(&mVector)) {
- return (vector->*insertDynamic)(std::forward<Args>(args)...);
+ if (Dynamic* const vector = std::get_if<Dynamic>(&vector_)) {
+ return (vector->*InsertDynamic)(std::forward<Args>(args)...);
}
- auto& vector = std::get<Static>(mVector);
+ auto& vector = std::get<Static>(vector_);
if (vector.full()) {
- return (promote(vector).*insertDynamic)(std::forward<Args>(args)...);
+ return (promote(vector).*InsertDynamic)(std::forward<Args>(args)...);
} else {
- return (vector.*insertStatic)(std::forward<Args>(args)...);
+ return (vector.*InsertStatic)(std::forward<Args>(args)...);
}
}
- Dynamic& promote(Static& staticVector) {
- assert(staticVector.full());
+ Dynamic& promote(Static& static_vector) {
+ assert(static_vector.full());
// Allocate double capacity to reduce probability of reallocation.
Dynamic vector;
vector.reserve(Static::max_size() * 2);
- std::move(staticVector.begin(), staticVector.end(), std::back_inserter(vector));
+ std::move(static_vector.begin(), static_vector.end(), std::back_inserter(vector));
- return mVector.template emplace<Dynamic>(std::move(vector));
+ return vector_.template emplace<Dynamic>(std::move(vector));
}
- std::variant<Static, Dynamic> mVector;
+ std::variant<Static, Dynamic> vector_;
};
// Partial specialization without static storage.
@@ -360,13 +360,13 @@
};
template <typename>
-struct IsSmallVector : std::false_type {};
+struct is_small_vector : std::false_type {};
-template <typename T, size_t N>
-struct IsSmallVector<SmallVector<T, N>> : std::true_type {};
+template <typename T, std::size_t N>
+struct is_small_vector<SmallVector<T, N>> : std::true_type {};
// Deduction guide for array constructor.
-template <typename T, size_t N>
+template <typename T, std::size_t N>
SmallVector(T (&)[N]) -> SmallVector<std::remove_cv_t<T>, N>;
// Deduction guide for variadic constructor.
@@ -375,15 +375,15 @@
SmallVector(T&&, Us&&...) -> SmallVector<V, 1 + sizeof...(Us)>;
// Deduction guide for in-place constructor.
-template <typename T, size_t... Sizes, typename... Types>
+template <typename T, std::size_t... Sizes, typename... Types>
SmallVector(InitializerList<T, std::index_sequence<Sizes...>, Types...>&&)
-> SmallVector<T, sizeof...(Sizes)>;
// Deduction guide for StaticVector conversion.
-template <typename T, size_t N>
+template <typename T, std::size_t N>
SmallVector(StaticVector<T, N>&&) -> SmallVector<T, N>;
-template <typename T, size_t N>
+template <typename T, std::size_t N>
inline void swap(SmallVector<T, N>& lhs, SmallVector<T, N>& rhs) {
lhs.swap(rhs);
}
diff --git a/include/ftl/StaticVector.h b/include/ftl/static_vector.h
similarity index 84%
rename from include/ftl/StaticVector.h
rename to include/ftl/static_vector.h
index c132556..5012175 100644
--- a/include/ftl/StaticVector.h
+++ b/include/ftl/static_vector.h
@@ -16,8 +16,8 @@
#pragma once
-#include <ftl/ArrayTraits.h>
-#include <ftl/InitializerList.h>
+#include <ftl/array_traits.h>
+#include <ftl/initializer_list.h>
#include <algorithm>
#include <cassert>
@@ -28,9 +28,9 @@
namespace android::ftl {
-constexpr struct IteratorRangeTag {} IteratorRange;
+constexpr struct IteratorRangeTag {} kIteratorRange;
-// Fixed-capacity, statically allocated counterpart of std::vector. Akin to std::array, StaticVector
+// Fixed-capacity, statically allocated counterpart of std::vector. Like std::array, StaticVector
// allocates contiguous storage for N elements of type T at compile time, but stores at most (rather
// than exactly) N elements. Unlike std::array, its default constructor does not require T to have a
// default constructor, since elements are constructed in place as the vector grows. Operations that
@@ -38,7 +38,8 @@
// adheres to standard containers, except the unstable_erase operation that does not preserve order,
// and the replace operation that destructively emplaces.
//
-// StaticVector<T, 1> is analogous to an iterable std::optional, but StaticVector<T, 0> is an error.
+// StaticVector<T, 1> is analogous to an iterable std::optional.
+// StaticVector<T, 0> is an error.
//
// Example usage:
//
@@ -72,7 +73,7 @@
// assert(strings[1] == "123");
// assert(strings[2] == "???");
//
-template <typename T, size_t N>
+template <typename T, std::size_t N>
class StaticVector final : ArrayTraits<T>,
ArrayIterators<StaticVector<T, N>, T>,
ArrayComparators<StaticVector> {
@@ -88,7 +89,7 @@
// latter unless they are input iterators and cannot be used to construct elements. If
// the former is intended, the caller can pass an IteratorRangeTag to disambiguate.
template <typename I, typename Traits = std::iterator_traits<I>>
- using IsInputIterator = std::conjunction<
+ using is_input_iterator = std::conjunction<
std::is_base_of<std::input_iterator_tag, typename Traits::iterator_category>,
std::negation<std::is_constructible<T, I>>>;
@@ -112,33 +113,34 @@
// Copies and moves a vector, respectively.
StaticVector(const StaticVector& other)
- : StaticVector(IteratorRange, other.begin(), other.end()) {}
- StaticVector(StaticVector&& other) { swap<Empty>(other); }
+ : StaticVector(kIteratorRange, other.begin(), other.end()) {}
+
+ StaticVector(StaticVector&& other) { swap<true>(other); }
// Copies at most N elements from a smaller convertible vector.
- template <typename U, size_t M, typename = std::enable_if_t<M <= N>>
+ template <typename U, std::size_t M, typename = std::enable_if_t<M <= N>>
StaticVector(const StaticVector<U, M>& other)
- : StaticVector(IteratorRange, other.begin(), other.end()) {}
+ : StaticVector(kIteratorRange, other.begin(), other.end()) {}
// Copies at most N elements from an array.
- template <typename U, size_t M>
+ template <typename U, std::size_t M>
explicit StaticVector(U (&array)[M])
- : StaticVector(IteratorRange, std::begin(array), std::end(array)) {}
+ : StaticVector(kIteratorRange, std::begin(array), std::end(array)) {}
// Copies at most N elements from the range [first, last).
//
// IteratorRangeTag disambiguates with initialization from two iterator-like elements.
//
- template <typename Iterator, typename = std::enable_if_t<IsInputIterator<Iterator>{}>>
- StaticVector(Iterator first, Iterator last) : StaticVector(IteratorRange, first, last) {
+ template <typename Iterator, typename = std::enable_if_t<is_input_iterator<Iterator>{}>>
+ StaticVector(Iterator first, Iterator last) : StaticVector(kIteratorRange, first, last) {
using V = typename std::iterator_traits<Iterator>::value_type;
static_assert(std::is_constructible_v<value_type, V>, "Incompatible iterator range");
}
template <typename Iterator>
StaticVector(IteratorRangeTag, Iterator first, Iterator last)
- : mSize(std::min(max_size(), static_cast<size_type>(std::distance(first, last)))) {
- std::uninitialized_copy(first, first + mSize, begin());
+ : size_(std::min(max_size(), static_cast<size_type>(std::distance(first, last)))) {
+ std::uninitialized_copy(first, first + size_, begin());
}
// Constructs at most N elements. The template arguments T and N are inferred using the
@@ -174,10 +176,10 @@
// assert(vector[1].empty());
// assert(vector[2] == "???");
//
- template <typename U, size_t Size, size_t... Sizes, typename... Types>
- StaticVector(InitializerList<U, std::index_sequence<Size, Sizes...>, Types...>&& init)
+ template <typename U, std::size_t Size, std::size_t... Sizes, typename... Types>
+ StaticVector(InitializerList<U, std::index_sequence<Size, Sizes...>, Types...>&& list)
: StaticVector(std::index_sequence<0, 0, Size>{}, std::make_index_sequence<Size>{},
- std::index_sequence<Sizes...>{}, init.tuple) {}
+ std::index_sequence<Sizes...>{}, list.tuple) {}
~StaticVector() { std::destroy(begin(), end()); }
@@ -189,21 +191,22 @@
StaticVector& operator=(StaticVector&& other) {
std::destroy(begin(), end());
- mSize = 0;
- swap<Empty>(other);
+ size_ = 0;
+ swap<true>(other);
return *this;
}
- template <typename = void>
+ // IsEmpty enables a fast path when the vector is known to be empty at compile time.
+ template <bool IsEmpty = false>
void swap(StaticVector&);
static constexpr size_type max_size() { return N; }
- size_type size() const { return mSize; }
+ size_type size() const { return size_; }
bool empty() const { return size() == 0; }
bool full() const { return size() == max_size(); }
- iterator begin() { return std::launder(reinterpret_cast<pointer>(mData)); }
+ iterator begin() { return std::launder(reinterpret_cast<pointer>(data_)); }
iterator end() { return begin() + size(); }
using Iter::begin;
@@ -252,7 +255,7 @@
iterator emplace_back(Args&&... args) {
if (full()) return end();
const iterator it = construct_at(end(), std::forward<Args>(args)...);
- ++mSize;
+ ++size_;
return it;
}
@@ -291,22 +294,20 @@
construct_at(it, std::move(back()));
std::destroy_at(last());
}
- --mSize;
+ --size_;
}
private:
- struct Empty {};
-
// Recursion for variadic constructor.
- template <size_t I, typename E, typename... Es>
+ template <std::size_t I, typename E, typename... Es>
StaticVector(std::index_sequence<I>, E&& element, Es&&... elements)
: StaticVector(std::index_sequence<I + 1>{}, std::forward<Es>(elements)...) {
construct_at(begin() + I, std::forward<E>(element));
}
// Base case for variadic constructor.
- template <size_t I>
- explicit StaticVector(std::index_sequence<I>) : mSize(I) {}
+ template <std::size_t I>
+ explicit StaticVector(std::index_sequence<I>) : size_(I) {}
// Recursion for in-place constructor.
//
@@ -317,29 +318,31 @@
// The Sizes sequence lists the argument counts for elements after I, so Size is the ArgCount
// for the next element. The recursion stops when Sizes is empty for the last element.
//
- template <size_t I, size_t ArgIndex, size_t ArgCount, size_t... Indices, size_t Size,
- size_t... Sizes, typename... Args>
+ template <std::size_t I, std::size_t ArgIndex, std::size_t ArgCount, std::size_t... Indices,
+ std::size_t Size, std::size_t... Sizes, typename... Args>
StaticVector(std::index_sequence<I, ArgIndex, ArgCount>, std::index_sequence<Indices...>,
std::index_sequence<Size, Sizes...>, std::tuple<Args...>& tuple)
: StaticVector(std::index_sequence<I + 1, ArgIndex + ArgCount, Size>{},
- std::make_index_sequence<Size>{}, std::index_sequence<Sizes...>{}, tuple) {
+ std::make_index_sequence<Size>{}, std::index_sequence<Sizes...>{},
+ tuple) {
construct_at(begin() + I, std::move(std::get<ArgIndex + Indices>(tuple))...);
}
// Base case for in-place constructor.
- template <size_t I, size_t ArgIndex, size_t ArgCount, size_t... Indices, typename... Args>
+ template <std::size_t I, std::size_t ArgIndex, std::size_t ArgCount, std::size_t... Indices,
+ typename... Args>
StaticVector(std::index_sequence<I, ArgIndex, ArgCount>, std::index_sequence<Indices...>,
std::index_sequence<>, std::tuple<Args...>& tuple)
- : mSize(I + 1) {
+ : size_(I + 1) {
construct_at(begin() + I, std::move(std::get<ArgIndex + Indices>(tuple))...);
}
- size_type mSize = 0;
- std::aligned_storage_t<sizeof(value_type), alignof(value_type)> mData[N];
+ size_type size_ = 0;
+ std::aligned_storage_t<sizeof(value_type), alignof(value_type)> data_[N];
};
// Deduction guide for array constructor.
-template <typename T, size_t N>
+template <typename T, std::size_t N>
StaticVector(T (&)[N]) -> StaticVector<std::remove_cv_t<T>, N>;
// Deduction guide for variadic constructor.
@@ -348,12 +351,12 @@
StaticVector(T&&, Us&&...) -> StaticVector<V, 1 + sizeof...(Us)>;
// Deduction guide for in-place constructor.
-template <typename T, size_t... Sizes, typename... Types>
+template <typename T, std::size_t... Sizes, typename... Types>
StaticVector(InitializerList<T, std::index_sequence<Sizes...>, Types...>&&)
-> StaticVector<T, sizeof...(Sizes)>;
-template <typename T, size_t N>
-template <typename E>
+template <typename T, std::size_t N>
+template <bool IsEmpty>
void StaticVector<T, N>::swap(StaticVector& other) {
auto [to, from] = std::make_pair(this, &other);
if (from == this) return;
@@ -362,7 +365,7 @@
auto [min, max] = std::make_pair(size(), other.size());
// No elements to swap if moving into an empty vector.
- if constexpr (std::is_same_v<E, Empty>) {
+ if constexpr (IsEmpty) {
assert(min == 0);
} else {
if (min > max) {
@@ -382,10 +385,10 @@
std::uninitialized_move(first, last, to->begin() + min);
std::destroy(first, last);
- std::swap(mSize, other.mSize);
+ std::swap(size_, other.size_);
}
-template <typename T, size_t N>
+template <typename T, std::size_t N>
inline void swap(StaticVector<T, N>& lhs, StaticVector<T, N>& rhs) {
lhs.swap(rhs);
}
diff --git a/libs/ftl/Android.bp b/libs/ftl/Android.bp
index eb8e57a..883d138 100644
--- a/libs/ftl/Android.bp
+++ b/libs/ftl/Android.bp
@@ -5,9 +5,9 @@
address: true,
},
srcs: [
- "SmallMap_test.cpp",
- "SmallVector_test.cpp",
- "StaticVector_test.cpp",
+ "small_map_test.cpp",
+ "small_vector_test.cpp",
+ "static_vector_test.cpp",
],
cflags: [
"-Wall",
diff --git a/libs/ftl/README.md b/libs/ftl/README.md
new file mode 100644
index 0000000..bdd750f
--- /dev/null
+++ b/libs/ftl/README.md
@@ -0,0 +1,41 @@
+# FTL
+
+FTL is a template library shared by SurfaceFlinger and InputFlinger, inspired by
+and supplementing the C++ Standard Library. The intent is to fill gaps for areas
+not (yet) covered—like cache-efficient data structures and lock-free concurrency
+primitives—and implement proposals that are missing or experimental in Android's
+libc++ branch. The design takes some liberties with standard compliance, notably
+assuming that exceptions are disabled.
+
+## Tests
+
+ atest ftl_test
+
+## Style
+
+- Based on [Google C++ Style](https://google.github.io/styleguide/cppguide.html).
+- Informed by [C++ Core Guidelines](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines).
+
+Naming conventions are as follows:
+
+- `PascalCase`
+ - Types and aliases, except standard interfaces.
+ - Template parameters, including non-type ones.
+- `snake_case`
+ - Variables, and data members with trailing underscore.
+ - Functions, free and member alike.
+ - Type traits, with standard `_t` and `_v` suffixes.
+- `kCamelCase`
+ - Enumerators and `constexpr` constants with static storage duration.
+- `MACRO_CASE`
+ - Macros, with `FTL_` prefix unless `#undef`ed.
+
+Template parameter packs are named with the following convention:
+
+ typename T, typename... Ts
+ typename Arg, typename... Args
+
+ std::size_t I, std::size_t... Is
+ std::size_t Size, std::size_t... Sizes
+
+The `details` namespace contains implementation details.
diff --git a/libs/ftl/SmallMap_test.cpp b/libs/ftl/small_map_test.cpp
similarity index 99%
rename from libs/ftl/SmallMap_test.cpp
rename to libs/ftl/small_map_test.cpp
index fa00c06..4e7662b 100644
--- a/libs/ftl/SmallMap_test.cpp
+++ b/libs/ftl/small_map_test.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include <ftl/SmallMap.h>
+#include <ftl/small_map.h>
#include <gtest/gtest.h>
#include <cctype>
diff --git a/libs/ftl/SmallVector_test.cpp b/libs/ftl/small_vector_test.cpp
similarity index 96%
rename from libs/ftl/SmallVector_test.cpp
rename to libs/ftl/small_vector_test.cpp
index d0c2858..dbb2d4f 100644
--- a/libs/ftl/SmallVector_test.cpp
+++ b/libs/ftl/small_vector_test.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include <ftl/SmallVector.h>
+#include <ftl/small_vector.h>
#include <gtest/gtest.h>
#include <algorithm>
@@ -72,8 +72,8 @@
}
{
// Array constructor.
- const float kFloats[] = {.1f, .2f, .3f};
- SmallVector vector(kFloats);
+ const float floats[] = {.1f, .2f, .3f};
+ SmallVector vector(floats);
EXPECT_EQ(vector, (SmallVector{.1f, .2f, .3f}));
EXPECT_FALSE(vector.dynamic());
@@ -149,8 +149,8 @@
EXPECT_STREQ(chars.begin(), "abcdefghij");
// Constructor takes iterator range.
- const char kString[] = "123456";
- SmallVector<char, 10> string(std::begin(kString), std::end(kString));
+ const char numbers[] = "123456";
+ SmallVector<char, 10> string(std::begin(numbers), std::end(numbers));
EXPECT_FALSE(string.dynamic());
EXPECT_STREQ(string.begin(), "123456");
@@ -171,7 +171,7 @@
TEST(SmallVector, CopyableElement) {
struct Pair {
- // Needed because std::vector emplace does not use uniform initialization.
+ // Needed because std::vector does not use list initialization to emplace.
Pair(int a, int b) : a(a), b(b) {}
const int a, b;
@@ -325,8 +325,8 @@
// Constructor takes array reference.
{
- const char* kStrings[] = {"cake", "lie"};
- strings = SmallVector(kStrings);
+ const char* array[] = {"cake", "lie"};
+ strings = SmallVector(array);
EXPECT_FALSE(strings.dynamic());
}
diff --git a/libs/ftl/StaticVector_test.cpp b/libs/ftl/static_vector_test.cpp
similarity index 95%
rename from libs/ftl/StaticVector_test.cpp
rename to libs/ftl/static_vector_test.cpp
index db42d23..3e66282 100644
--- a/libs/ftl/StaticVector_test.cpp
+++ b/libs/ftl/static_vector_test.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include <ftl/StaticVector.h>
+#include <ftl/static_vector.h>
#include <gtest/gtest.h>
#include <algorithm>
@@ -68,8 +68,8 @@
}
{
// Array constructor.
- const float kFloats[] = {.1f, .2f, .3f};
- StaticVector vector(kFloats);
+ const float floats[] = {.1f, .2f, .3f};
+ StaticVector vector(floats);
EXPECT_EQ(vector, (StaticVector{.1f, .2f, .3f}));
}
{
@@ -122,11 +122,11 @@
const char* str;
};
- const char* kStrings[] = {"a", "b", "c", "d"};
+ const char* strings[] = {"a", "b", "c", "d"};
{
// Two iterator-like elements.
- StaticVector<String, 3> vector(kStrings, kStrings + 3);
+ StaticVector<String, 3> vector(strings, strings + 3);
ASSERT_EQ(vector.size(), 2u);
EXPECT_STREQ(vector[0].str, "a");
@@ -134,7 +134,7 @@
}
{
// Disambiguating iterator constructor.
- StaticVector<String, 3> vector(ftl::IteratorRange, kStrings, kStrings + 3);
+ StaticVector<String, 3> vector(ftl::kIteratorRange, strings, strings + 3);
ASSERT_EQ(vector.size(), 3u);
EXPECT_STREQ(vector[0].str, "a");
@@ -153,8 +153,8 @@
EXPECT_STREQ(chars.begin(), "abcdefghi");
// Constructor takes iterator range.
- const char kString[] = "123456";
- StaticVector<char, 10> string(std::begin(kString), std::end(kString));
+ const char numbers[] = "123456";
+ StaticVector<char, 10> string(std::begin(numbers), std::end(numbers));
EXPECT_STREQ(string.begin(), "123456");
EXPECT_EQ(string.size(), 7u);
@@ -290,8 +290,8 @@
// Constructor takes array reference.
{
- const char* kStrings[] = {"cake", "lie"};
- strings = StaticVector(kStrings);
+ const char* array[] = {"cake", "lie"};
+ strings = StaticVector(array);
}
EXPECT_GT(sorted, strings);