fd/atomic: Better separate this orthogonal functionality

Nothing is using the old interface, so we can move it for better
separation of responisbilities.

Change-Id: I3b6e429b106aa22e58df25e0801b60af0fbd6d70
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/include-fd/meson.build b/include-fd/meson.build
index 1e85293..3e36cb8 100644
--- a/include-fd/meson.build
+++ b/include-fd/meson.build
@@ -1,6 +1,7 @@
 stdplus_headers += include_directories('.')
 
 install_headers(
+  'stdplus/fd/atomic.hpp',
   'stdplus/fd/create.hpp',
   'stdplus/fd/dupable.hpp',
   'stdplus/fd/fmt.hpp',
diff --git a/include-fd/stdplus/fd/atomic.hpp b/include-fd/stdplus/fd/atomic.hpp
new file mode 100644
index 0000000..904e706
--- /dev/null
+++ b/include-fd/stdplus/fd/atomic.hpp
@@ -0,0 +1,40 @@
+#pragma once
+#include <filesystem>
+#include <stdplus/fd/managed.hpp>
+#include <string>
+#include <string_view>
+
+namespace stdplus
+{
+namespace fd
+{
+
+class AtomicWriter : public stdplus::FdImpl
+{
+  public:
+    AtomicWriter(const std::filesystem::path& filename, int mode,
+                 std::string_view tmpl = {});
+    AtomicWriter(AtomicWriter&& other);
+    AtomicWriter& operator=(AtomicWriter&& other);
+    ~AtomicWriter();
+
+    void commit(bool allow_copy = false);
+
+    inline const std::string& getTmpname() const
+    {
+        return tmpname;
+    }
+
+    int get() const override;
+
+  private:
+    std::filesystem::path filename;
+    int mode;
+    std::string tmpname;
+    ManagedFd fd;
+
+    void cleanup() noexcept;
+};
+
+} // namespace fd
+} // namespace stdplus
diff --git a/include-fd/stdplus/fd/fmt.hpp b/include-fd/stdplus/fd/fmt.hpp
index b0e4c11..de77b68 100644
--- a/include-fd/stdplus/fd/fmt.hpp
+++ b/include-fd/stdplus/fd/fmt.hpp
@@ -1,11 +1,9 @@
 #pragma once
-#include <filesystem>
 #include <fmt/format.h>
 #include <functional>
 #include <stdplus/fd/intf.hpp>
-#include <stdplus/fd/managed.hpp>
-#include <string_view>
 #include <type_traits>
+#include <utility>
 
 namespace fmt
 {
@@ -58,41 +56,5 @@
     void writeIfNeeded();
 };
 
-class FormatToFile
-{
-  public:
-    explicit FormatToFile(std::string_view tmpl = "/tmp/stdplus.XXXXXX");
-    ~FormatToFile();
-    FormatToFile(const FormatToFile&) = delete;
-    FormatToFile(FormatToFile&&) = delete;
-    FormatToFile& operator=(const FormatToFile&) = delete;
-    FormatToFile& operator=(FormatToFile&&) = delete;
-
-    template <typename... Args>
-    inline void append(fmt::format_string<Args...> fmt, Args&&... args)
-    {
-        buf.append(fmt, std::forward<Args>(args)...);
-    }
-    template <typename T, typename... Args,
-              std::enable_if_t<fmt::detail::is_compiled_string<T>::value,
-                               bool> = true>
-    inline void append(const T& t, Args&&... args)
-    {
-        buf.append(t, std::forward<Args>(args)...);
-    }
-
-    void commit(const std::filesystem::path& out, int mode = 0644);
-
-    inline const std::string& getTmpname() const
-    {
-        return tmpname;
-    }
-
-  private:
-    std::string tmpname;
-    ManagedFd fd;
-    FormatBuffer buf;
-};
-
 } // namespace fd
 } // namespace stdplus