#endif
#include <ctype.h>
+#include <float.h>
#include <string.h>
#include <iomanip>
#include <limits>
#include <set>
+#include <string>
+#include <vector>
#include "gtest/gtest-message.h"
#include "gtest/internal/gtest-string.h"
// c'tor and d'tor. Therefore it doesn't
// need to be used otherwise.
+namespace edit_distance {
+// Returns the optimal edits to go from 'left' to 'right'.
+// All edits cost the same, with replace having lower priority than
+// add/remove.
+// Simple implementation of the Wagner–Fischer algorithm.
+// See http://en.wikipedia.org/wiki/Wagner-Fischer_algorithm
+enum EditType { kMatch, kAdd, kRemove, kReplace };
+GTEST_API_ std::vector<EditType> CalculateOptimalEdits(
+ const std::vector<size_t>& left, const std::vector<size_t>& right);
+
+// Same as above, but the input is represented as strings.
+GTEST_API_ std::vector<EditType> CalculateOptimalEdits(
+ const std::vector<std::string>& left,
+ const std::vector<std::string>& right);
+
+// Create a diff of the input strings in Unified diff format.
+GTEST_API_ std::string CreateUnifiedDiff(const std::vector<std::string>& left,
+ const std::vector<std::string>& right,
+ size_t context = 2);
+
+} // namespace edit_distance
+
+// Calculate the diff between 'left' and 'right' and return it in unified diff
+// format.
+// If not null, stores in 'total_line_count' the total number of lines found
+// in left + right.
+GTEST_API_ std::string DiffStrings(const std::string& left,
+ const std::string& right,
+ size_t* total_line_count);
+
// Constructs and returns the message for an equality assertion
// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure.
//
return ReinterpretBits(kExponentBitMask);
}
+ // Returns the maximum representable finite floating-point number.
+ static RawType Max();
+
// Non-static methods
// Returns the bits that represents this number.
FloatingPointUnion u_;
};
+// We cannot use std::numeric_limits<T>::max() as it clashes with the max()
+// macro defined by <windows.h>.
+template <>
+inline float FloatingPoint<float>::Max() { return FLT_MAX; }
+template <>
+inline double FloatingPoint<double>::Max() { return DBL_MAX; }
+
// Typedefs the instances of the FloatingPoint template class that we
// care to use.
typedef FloatingPoint<float> Float;
// MakeFrom() is an expression whose type is From. We cannot simply
// use From(), as the type From may not have a public default
// constructor.
- static From MakeFrom();
+ static typename AddReference<From>::type MakeFrom();
// These two functions are overloaded. Given an expression
// Helper(x), the compiler will pick the first version if x can be
// We have to put the 'public' section after the 'private' section,
// or MSVC refuses to compile the code.
public:
- // MSVC warns about implicitly converting from double to int for
- // possible loss of data, so we need to temporarily disable the
- // warning.
-#ifdef _MSC_VER
-# pragma warning(push) // Saves the current warning state.
-# pragma warning(disable:4244) // Temporarily disables warning 4244.
-
- static const bool value =
- sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1;
-# pragma warning(pop) // Restores the warning state.
-#elif defined(__BORLANDC__)
+#if defined(__BORLANDC__)
// C++Builder cannot use member overload resolution during template
// instantiation. The simplest workaround is to use its C++0x type traits
// functions (C++Builder 2009 and above only).
static const bool value = __is_convertible(From, To);
#else
+ // MSVC warns about implicitly converting from double to int for
+ // possible loss of data, so we need to temporarily disable the
+ // warning.
+ GTEST_DISABLE_MSC_WARNINGS_PUSH_(4244)
static const bool value =
sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1;
-#endif // _MSV_VER
+ GTEST_DISABLE_MSC_WARNINGS_POP_()
+#endif // __BORLANDC__
};
template <typename From, typename To>
const bool ImplicitlyConvertible<From, To>::value;
// The relation between an NativeArray object (see below) and the
// native array it represents.
-enum RelationToSource {
- kReference, // The NativeArray references the native array.
- kCopy // The NativeArray makes a copy of the native array and
- // owns the copy.
-};
+// We use 2 different structs to allow non-copyable types to be used, as long
+// as RelationToSourceReference() is passed.
+struct RelationToSourceReference {};
+struct RelationToSourceCopy {};
// Adapts a native array to a read-only STL-style container. Instead
// of the complete STL container concept, this adaptor only implements
typedef Element* iterator;
typedef const Element* const_iterator;
- // Constructs from a native array.
- NativeArray(const Element* array, size_t count, RelationToSource relation) {
- Init(array, count, relation);
+ // Constructs from a native array. References the source.
+ NativeArray(const Element* array, size_t count, RelationToSourceReference) {
+ InitRef(array, count);
+ }
+
+ // Constructs from a native array. Copies the source.
+ NativeArray(const Element* array, size_t count, RelationToSourceCopy) {
+ InitCopy(array, count);
}
// Copy constructor.
NativeArray(const NativeArray& rhs) {
- Init(rhs.array_, rhs.size_, rhs.relation_to_source_);
+ (this->*rhs.clone_)(rhs.array_, rhs.size_);
}
~NativeArray() {
- // Ensures that the user doesn't instantiate NativeArray with a
- // const or reference type.
- static_cast<void>(StaticAssertTypeEqHelper<Element,
- GTEST_REMOVE_REFERENCE_AND_CONST_(Element)>());
- if (relation_to_source_ == kCopy)
+ if (clone_ != &NativeArray::InitRef)
delete[] array_;
}
}
private:
- // Initializes this object; makes a copy of the input array if
- // 'relation' is kCopy.
- void Init(const Element* array, size_t a_size, RelationToSource relation) {
- if (relation == kReference) {
- array_ = array;
- } else {
- Element* const copy = new Element[a_size];
- CopyArray(array, a_size, copy);
- array_ = copy;
- }
+ enum {
+ kCheckTypeIsNotConstOrAReference = StaticAssertTypeEqHelper<
+ Element, GTEST_REMOVE_REFERENCE_AND_CONST_(Element)>::value,
+ };
+
+ // Initializes this object with a copy of the input.
+ void InitCopy(const Element* array, size_t a_size) {
+ Element* const copy = new Element[a_size];
+ CopyArray(array, a_size, copy);
+ array_ = copy;
size_ = a_size;
- relation_to_source_ = relation;
+ clone_ = &NativeArray::InitCopy;
+ }
+
+ // Initializes this object with a reference of the input.
+ void InitRef(const Element* array, size_t a_size) {
+ array_ = array;
+ size_ = a_size;
+ clone_ = &NativeArray::InitRef;
}
const Element* array_;
size_t size_;
- RelationToSource relation_to_source_;
+ void (NativeArray::*clone_)(const Element*, size_t);
GTEST_DISALLOW_ASSIGN_(NativeArray);
};
void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
+