+/**
+ * Changes into a temporary directory, and deletes it with all its contents
+ * upon destruction, also changing back to the original working directory.
+ */
+class ChangeToTempDir {
+ public:
+ ChangeToTempDir();
+ ~ChangeToTempDir();
+
+ // Movable, but not copiable
+ ChangeToTempDir(ChangeToTempDir&&) = default;
+ ChangeToTempDir& operator=(ChangeToTempDir&&) = default;
+
+ const fs::path& path() const { return dir_.path(); }
+
+ private:
+ fs::path initialPath_;
+ TemporaryDirectory dir_;
+};
+
+namespace detail {
+struct SavedState {
+ void* previousThreadLocalHandler;
+ int previousCrtReportMode;
+};
+SavedState disableInvalidParameters();
+void enableInvalidParameters(SavedState state);
+} // namespace detail
+
+// Ok, so fun fact: The CRT on windows will actually abort
+// on certain failed parameter validation checks in debug
+// mode rather than simply returning -1 as it does in release
+// mode. We can however, ensure consistent behavior by
+// registering our own thread-local invalid parameter handler
+// for the duration of the call, and just have that handler
+// immediately return. We also have to disable CRT asertion
+// alerts for the duration of the call, otherwise we get
+// the abort-retry-ignore window.
+template <typename Func>
+auto msvcSuppressAbortOnInvalidParams(Func func) -> decltype(func()) {
+ auto savedState = detail::disableInvalidParameters();
+ SCOPE_EXIT {
+ detail::enableInvalidParameters(savedState);
+ };
+ return func();
+}
+
+/**
+ * Easy PCRE regex matching. Note that pattern must match the ENTIRE target,
+ * so use .* at the start and end of the pattern, as appropriate. See
+ * http://regex101.com/ for a PCRE simulator.
+ */
+#define EXPECT_PCRE_MATCH(pattern_stringpiece, target_stringpiece) \
+ EXPECT_PRED2( \
+ ::folly::test::detail::hasPCREPatternMatch, \
+ pattern_stringpiece, \
+ target_stringpiece \
+ )
+#define EXPECT_NO_PCRE_MATCH(pattern_stringpiece, target_stringpiece) \
+ EXPECT_PRED2( \
+ ::folly::test::detail::hasNoPCREPatternMatch, \
+ pattern_stringpiece, \
+ target_stringpiece \
+ )