From e4552a8b179e664446f8c480624ca00b0cec8dcb Mon Sep 17 00:00:00 2001
From: Avi Kivity <avi@cloudius-systems.com>
Date: Tue, 3 Dec 2013 14:45:16 +0200
Subject: [PATCH] file: generalize make_file() to be able to create derived
 types

Signed-off-by: Avi Kivity <avi@cloudius-systems.com>
---
 fs/fs.hh               | 23 +++++++++++++++--------
 fs/vfs/kern_descrip.cc | 10 ----------
 2 files changed, 15 insertions(+), 18 deletions(-)

diff --git a/fs/fs.hh b/fs/fs.hh
index f66c0d1ca..95d776152 100644
--- a/fs/fs.hh
+++ b/fs/fs.hh
@@ -13,6 +13,7 @@
 #include <cstdint>
 #include <boost/intrusive_ptr.hpp>
 #include <osv/file.h>
+#include <utility>
 
 static inline void intrusive_ptr_add_ref(file *fp)
 {
@@ -43,23 +44,29 @@ uint64_t size(fileref f);
 void read(fileref f, void *buffer, uint64_t offset, uint64_t len);
 void write(fileref f, const void* buffer, uint64_t offset, uint64_t len);
 
-template <class file_type = file>
+template <class file_type, typename... args>
 fileref
-make_file(unsigned flags, filetype_t type,
-        void *opaque, struct fileops *ops)
+make_file(args&&... a)
 {
-    file* fp = new (std::nothrow) file_type(flags, type, opaque, ops);
+    file* fp = new (std::nothrow) file_type(std::forward<args>(a)...);
     if (!fp) {
         throw ENOMEM;
     }
     return fileref(fp, false);
 }
 
-template <class T, class file_type = file>
-fileref make_file(unsigned flags, filetype_t type,
-        std::unique_ptr<T>&& opaque, struct fileops *ops)
+inline
+fileref make_file(unsigned flags, filetype_t type, void *opaque,
+        struct fileops *ops)
 {
-    auto f = make_file<file_type>(flags, type, opaque.get(), ops);
+    return make_file<file>(flags, type, opaque, ops);
+}
+
+template <typename T>
+fileref make_file(unsigned flags, filetype_t type, std::unique_ptr<T>&& opaque,
+        struct fileops *ops)
+{
+    auto f = make_file<file>(flags, type, opaque.get(), ops);
     opaque.release();
     return f;
 }
diff --git a/fs/vfs/kern_descrip.cc b/fs/vfs/kern_descrip.cc
index 6983bcf6e..3b9892e4b 100644
--- a/fs/vfs/kern_descrip.cc
+++ b/fs/vfs/kern_descrip.cc
@@ -166,16 +166,6 @@ file::file(unsigned flags, filetype_t type, void *opaque,
     fo_init(fp);
 }
 
-fileref make_file(unsigned flags, filetype_t type, void *opaque,
-        struct fileops *ops)
-{
-    file* fp = new (std::nothrow) file(flags, type, opaque, ops);
-    if (!fp) {
-        throw ENOMEM;
-    }
-    return fileref(fp, false);
-}
-
 void fhold(struct file* fp)
 {
     __sync_fetch_and_add(&fp->f_count, 1);
-- 
GitLab