[llvm] r290020 - Add support for formatv to llvm::Twine.
Zachary Turner via llvm-commits
llvm-commits at lists.llvm.org
Fri Dec 16 16:38:15 PST 2016
Author: zturner
Date: Fri Dec 16 18:38:15 2016
New Revision: 290020
URL: http://llvm.org/viewvc/llvm-project?rev=290020&view=rev
Log:
Add support for formatv to llvm::Twine.
Differential Revision: https://reviews.llvm.org/D27835
Modified:
llvm/trunk/include/llvm/ADT/Twine.h
llvm/trunk/lib/Support/Twine.cpp
llvm/trunk/unittests/ADT/TwineTest.cpp
Modified: llvm/trunk/include/llvm/ADT/Twine.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/Twine.h?rev=290020&r1=290019&r2=290020&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/Twine.h (original)
+++ llvm/trunk/include/llvm/ADT/Twine.h Fri Dec 16 18:38:15 2016
@@ -19,6 +19,7 @@
namespace llvm {
+ class formatv_object_base;
class raw_ostream;
/// Twine - A lightweight data structure for efficiently representing the
@@ -102,6 +103,9 @@ namespace llvm {
/// A pointer to a SmallString instance.
SmallStringKind,
+ /// A pointer to a formatv_object_base instance.
+ FormatvObjectKind,
+
/// A char value, to render as a character.
CharKind,
@@ -137,6 +141,7 @@ namespace llvm {
const std::string *stdString;
const StringRef *stringRef;
const SmallVectorImpl<char> *smallString;
+ const formatv_object_base *formatvObject;
char character;
unsigned int decUI;
int decI;
@@ -290,6 +295,13 @@ namespace llvm {
assert(isValid() && "Invalid twine!");
}
+ /// Construct from a formatv_object_base.
+ /*implicit*/ Twine(const formatv_object_base &Fmt)
+ : LHSKind(FormatvObjectKind), RHSKind(EmptyKind) {
+ LHS.formatvObject = &Fmt;
+ assert(isValid() && "Invalid twine!");
+ }
+
/// Construct from a char.
explicit Twine(char Val)
: LHSKind(CharKind), RHSKind(EmptyKind) {
Modified: llvm/trunk/lib/Support/Twine.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Twine.cpp?rev=290020&r1=290019&r2=290020&view=diff
==============================================================================
--- llvm/trunk/lib/Support/Twine.cpp (original)
+++ llvm/trunk/lib/Support/Twine.cpp Fri Dec 16 18:38:15 2016
@@ -10,6 +10,7 @@
#include "llvm/ADT/Twine.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
@@ -18,6 +19,11 @@ std::string Twine::str() const {
if (LHSKind == StdStringKind && RHSKind == EmptyKind)
return *LHS.stdString;
+ // If we're storing a formatv_object, we can avoid an extra copy by formatting
+ // it immediately and returning the result.
+ if (LHSKind == FormatvObjectKind && RHSKind == EmptyKind)
+ return LHS.formatvObject->str();
+
// Otherwise, flatten and copy the contents first.
SmallString<256> Vec;
return toStringRef(Vec).str();
@@ -68,6 +74,9 @@ void Twine::printOneChild(raw_ostream &O
case Twine::SmallStringKind:
OS << *Ptr.smallString;
break;
+ case Twine::FormatvObjectKind:
+ OS << *Ptr.formatvObject;
+ break;
case Twine::CharKind:
OS << Ptr.character;
break;
@@ -121,6 +130,9 @@ void Twine::printOneChildRepr(raw_ostrea
case Twine::SmallStringKind:
OS << "smallstring:\"" << *Ptr.smallString << "\"";
break;
+ case Twine::FormatvObjectKind:
+ OS << "formatv:\"" << *Ptr.formatvObject << "\"";
+ break;
case Twine::CharKind:
OS << "char:\"" << Ptr.character << "\"";
break;
Modified: llvm/trunk/unittests/ADT/TwineTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/TwineTest.cpp?rev=290020&r1=290019&r2=290020&view=diff
==============================================================================
--- llvm/trunk/unittests/ADT/TwineTest.cpp (original)
+++ llvm/trunk/unittests/ADT/TwineTest.cpp Fri Dec 16 18:38:15 2016
@@ -7,8 +7,10 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/ADT/Twine.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/FormatAdapters.h"
+#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/raw_ostream.h"
#include "gtest/gtest.h"
using namespace llvm;
@@ -30,6 +32,7 @@ TEST(TwineTest, Construction) {
EXPECT_EQ("hi", Twine(StringRef(std::string("hi"))).str());
EXPECT_EQ("hi", Twine(StringRef("hithere", 2)).str());
EXPECT_EQ("hi", Twine(SmallString<4>("hi")).str());
+ EXPECT_EQ("hi", Twine(formatv("{0}", "hi")).str());
}
TEST(TwineTest, Numbers) {
@@ -65,6 +68,10 @@ TEST(TwineTest, Concat) {
repr(Twine().concat(Twine("hi"))));
EXPECT_EQ("(Twine smallstring:\"hi\" empty)",
repr(Twine().concat(Twine(SmallString<5>("hi")))));
+ EXPECT_EQ("(Twine formatv:\"howdy\" empty)",
+ repr(Twine(formatv("howdy")).concat(Twine())));
+ EXPECT_EQ("(Twine formatv:\"howdy\" empty)",
+ repr(Twine().concat(Twine(formatv("howdy")))));
EXPECT_EQ("(Twine smallstring:\"hey\" cstring:\"there\")",
repr(Twine(SmallString<7>("hey")).concat(Twine("there"))));
@@ -89,6 +96,25 @@ TEST(TwineTest, toNullTerminatedStringRe
EXPECT_EQ(0, *Twine(SmallString<11>("hello"))
.toNullTerminatedStringRef(storage)
.end());
+ EXPECT_EQ(0, *Twine(formatv("{0}{1}", "how", "dy"))
+ .toNullTerminatedStringRef(storage)
+ .end());
+}
+
+TEST(TwineTest, LazyEvaluation) {
+ struct formatter : FormatAdapter<int> {
+ explicit formatter(int &Count) : Count(Count), FormatAdapter(0) {}
+ int &Count;
+
+ void format(raw_ostream &OS, StringRef Style) { ++Count; }
+ };
+
+ int Count = 0;
+ formatter Formatter(Count);
+ (void)Twine(formatv("{0}", Formatter));
+ EXPECT_EQ(0, Count);
+ (void)Twine(formatv("{0}", Formatter)).str();
+ EXPECT_EQ(1, Count);
}
// I suppose linking in the entire code generator to add a unit test to check
More information about the llvm-commits
mailing list