Add resizing constructor to folly::padded::Adaptor
authorTudor Bosman <tudorb@fb.com>
Tue, 5 Mar 2013 00:31:58 +0000 (16:31 -0800)
committerJordan DeLong <jdelong@fb.com>
Tue, 19 Mar 2013 00:08:12 +0000 (17:08 -0700)
Summary: Added Adaptor(size_t, const value_type&)

Test Plan: test added

Reviewed By: soren@fb.com

FB internal diff: D726358

folly/Padded.h
folly/test/PaddedTest.cpp

index f4d3b9c7af57d72deb2f644d015bf2e4fbb61ccf..6de44a3bc13feef8768361e63c791616171e44b9 100644 (file)
@@ -343,6 +343,11 @@ class Adaptor {
     : c_(std::move(c)),
       lastCount_(lastCount) {
   }
+  explicit Adaptor(size_t n, const value_type& value = value_type())
+    : c_(Node::nodeCount(n), fullNode(value)),
+      lastCount_(n % Node::kElementCount ?: Node::kElementCount) {
+  }
+
   Adaptor(const Adaptor&) = default;
   Adaptor& operator=(const Adaptor&) = default;
   Adaptor(Adaptor&& other)
@@ -444,6 +449,7 @@ class Adaptor {
     assert(n >= 0);
     c_.reserve(Node::nodeCount(n));
   }
+
   size_type capacity() const {
     return c_.capacity() * Node::kElementCount;
   }
@@ -475,12 +481,20 @@ class Adaptor {
   }
 
   void padToFullNode(const value_type& padValue) {
-    while (lastCount_ != Node::kElementCount) {
-      push_back(padValue);
+    // the if is necessary because c_ may be empty so we can't call c_.back()
+    if (lastCount_ != Node::kElementCount) {
+      auto last = c_.back().data();
+      std::fill(last + lastCount_, last + Node::kElementCount, padValue);
+      lastCount_ = Node::kElementCount;
     }
   }
 
  private:
+  static Node fullNode(const value_type& value) {
+    Node n;
+    std::fill(n.data(), n.data() + kElementsPerNode, value);
+    return n;
+  }
   Container c_;  // container of Nodes
   size_t lastCount_;  // number of elements in last Node
 };
index f5fde4845bd89d2b0ed807ee785dc784690de2f4..32ef47627a5f3dee7ae7973ec85337f0c93fa479 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2012 Facebook, Inc.
+ * Copyright 2013 Facebook, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 #include <gtest/gtest.h>
 
 using namespace folly;
-namespace ps = ::folly::padded;
 
 TEST(NodeTest, Padding) {
-  typedef ps::Node<int32_t, 64> IntNode;
+  typedef padded::Node<int32_t, 64> IntNode;
   EXPECT_EQ(16, IntNode::kElementCount);
   EXPECT_EQ(0, IntNode::kPaddingBytes);
   EXPECT_EQ(alignof(int32_t), alignof(IntNode));
@@ -50,7 +49,7 @@ TEST(NodeTest, Padding) {
     char c[7];
   };
   EXPECT_EQ(1, alignof(SevenBytes));
-  typedef ps::Node<SevenBytes, 64> SevenByteNode;
+  typedef padded::Node<SevenBytes, 64> SevenByteNode;
   EXPECT_EQ(9, SevenByteNode::kElementCount);  // 64 / 7
   EXPECT_EQ(1, SevenByteNode::kPaddingBytes);  // 64 % 7
   EXPECT_EQ(1, alignof(SevenByteNode));
@@ -77,7 +76,7 @@ TEST(NodeTest, Padding) {
 
 class IntPaddedTestBase : public ::testing::Test {
  protected:
-  typedef ps::Node<uint32_t, 64> IntNode;
+  typedef padded::Node<uint32_t, 64> IntNode;
   typedef std::vector<IntNode> IntNodeVec;
   IntNodeVec v_;
   int n_;
@@ -98,16 +97,16 @@ class IntPaddedConstTest : public IntPaddedTestBase {
 
 TEST_F(IntPaddedConstTest, Iteration) {
   int k = 0;
-  for (auto it = ps::cbegin(v_); it != ps::cend(v_); ++it, ++k) {
+  for (auto it = padded::cbegin(v_); it != padded::cend(v_); ++it, ++k) {
     EXPECT_EQ(k, *it);
   }
   EXPECT_EQ(n_, k);
 }
 
 TEST_F(IntPaddedConstTest, Arithmetic) {
-  EXPECT_EQ(64, ps::cend(v_) - ps::cbegin(v_));
+  EXPECT_EQ(64, padded::cend(v_) - padded::cbegin(v_));
   // Play around block boundaries
-  auto it = ps::cbegin(v_);
+  auto it = padded::cbegin(v_);
   EXPECT_EQ(0, *it);
   {
     auto i2 = it;
@@ -154,7 +153,7 @@ TEST_F(IntPaddedNonConstTest, Iteration) {
   n_ = 64;
 
   int k = 0;
-  for (auto it = ps::begin(v_); it != ps::end(v_); ++it, ++k) {
+  for (auto it = padded::begin(v_); it != padded::end(v_); ++it, ++k) {
     *it = k;
   }
   EXPECT_EQ(n_, k);
@@ -174,7 +173,7 @@ class StructPaddedTestBase : public ::testing::Test {
     uint8_t y;
     uint8_t z;
   };
-  typedef ps::Node<Point, 64> PointNode;
+  typedef padded::Node<Point, 64> PointNode;
   typedef std::vector<PointNode> PointNodeVec;
   PointNodeVec v_;
   int n_;
@@ -198,7 +197,7 @@ class StructPaddedConstTest : public StructPaddedTestBase {
 
 TEST_F(StructPaddedConstTest, Iteration) {
   int k = 0;
-  for (auto it = ps::cbegin(v_); it != ps::cend(v_); ++it, ++k) {
+  for (auto it = padded::cbegin(v_); it != padded::cend(v_); ++it, ++k) {
     EXPECT_EQ(k, it->x);
     EXPECT_EQ(k + 1, it->y);
     EXPECT_EQ(k + 2, it->z);
@@ -208,7 +207,7 @@ TEST_F(StructPaddedConstTest, Iteration) {
 
 class IntAdaptorTest : public IntPaddedConstTest {
  protected:
-  typedef ps::Adaptor<IntNodeVec> IntAdaptor;
+  typedef padded::Adaptor<IntNodeVec> IntAdaptor;
   IntAdaptor a_;
 };
 
@@ -232,3 +231,12 @@ TEST_F(IntAdaptorTest, Simple) {
   EXPECT_EQ(16, p.second);
   EXPECT_TRUE(v_ == p.first);
 }
+
+TEST_F(IntAdaptorTest, ResizeConstructor) {
+  IntAdaptor a(n_, 42);
+  EXPECT_EQ(n_, a.size());
+  for (int i = 0; i < n_; ++i) {
+    EXPECT_EQ(42, a[i]);
+  }
+}
+