Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnkit Meel <ankitjmeel@gmail.com>2022-01-21 12:15:21 +0300
committerAnkit Meel <ankitjmeel@gmail.com>2022-01-21 12:58:04 +0300
commit36c40760a5a38db733e20c948b2170ab78bb2607 (patch)
treea760b7f4c98915e96018fb8b3decf1d84ca8acd8
parent23fa5bb723049684b06192afbdd1714e4109be72 (diff)
.obj: simplify templates in FileHandler, add comments
- Remove redundant template from `FormattingSyntax`. - Replace one enable_if with static assert for readability - Add comments No functional change expected. Reviewed by: jacqueslucke Differential Revision: https://developer.blender.org/D13882
-rw-r--r--source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc2
-rw-r--r--source/blender/io/wavefront_obj/exporter/obj_export_file_writer.hh6
-rw-r--r--source/blender/io/wavefront_obj/exporter/obj_export_io.hh82
3 files changed, 51 insertions, 39 deletions
diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc b/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc
index 8c845c34db2..d31353c4a76 100644
--- a/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc
+++ b/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc
@@ -394,7 +394,7 @@ MTLWriter::MTLWriter(const char *obj_filepath) noexcept(false)
if (!ok) {
throw std::system_error(ENAMETOOLONG, std::system_category(), "");
}
- file_handler_ = std::make_unique<FileHandler<eFileType::MTL>>(mtl_filepath_);
+ file_handler_ = std::make_unique<FormattedFileHandler<eFileType::MTL>>(mtl_filepath_);
}
void MTLWriter::write_header(const char *blen_filepath) const
diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.hh b/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.hh
index 1cad179a70c..7385d9fabe2 100644
--- a/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.hh
+++ b/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.hh
@@ -49,14 +49,14 @@ struct IndexOffsets {
class OBJWriter : NonMovable, NonCopyable {
private:
const OBJExportParams &export_params_;
- std::unique_ptr<FileHandler<eFileType::OBJ>> file_handler_ = nullptr;
+ std::unique_ptr<FormattedFileHandler<eFileType::OBJ>> file_handler_ = nullptr;
IndexOffsets index_offsets_{0, 0, 0};
public:
OBJWriter(const char *filepath, const OBJExportParams &export_params) noexcept(false)
: export_params_(export_params)
{
- file_handler_ = std::make_unique<FileHandler<eFileType::OBJ>>(filepath);
+ file_handler_ = std::make_unique<FormattedFileHandler<eFileType::OBJ>>(filepath);
}
void write_header() const;
@@ -172,7 +172,7 @@ class OBJWriter : NonMovable, NonCopyable {
*/
class MTLWriter : NonMovable, NonCopyable {
private:
- std::unique_ptr<FileHandler<eFileType::MTL>> file_handler_ = nullptr;
+ std::unique_ptr<FormattedFileHandler<eFileType::MTL>> file_handler_ = nullptr;
std::string mtl_filepath_;
Vector<MTLMaterial> mtlmaterials_;
/* Map from a Material* to an index into mtlmaterials_. */
diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_io.hh b/source/blender/io/wavefront_obj/exporter/obj_export_io.hh
index a6f0174d68b..e88a76fc4e8 100644
--- a/source/blender/io/wavefront_obj/exporter/obj_export_io.hh
+++ b/source/blender/io/wavefront_obj/exporter/obj_export_io.hh
@@ -88,6 +88,7 @@ enum class eMTLSyntaxElement {
template<eFileType filetype> struct FileTypeTraits;
+/* Used to prevent mixing of say OBJ file format with MTL syntax elements. */
template<> struct FileTypeTraits<eFileType::OBJ> {
using SyntaxType = eOBJSyntaxElement;
};
@@ -96,15 +97,19 @@ template<> struct FileTypeTraits<eFileType::MTL> {
using SyntaxType = eMTLSyntaxElement;
};
-template<eFileType type> struct Formatting {
+struct FormattingSyntax {
+ /* Formatting syntax with the file format key like `newmtl %s\n`. */
const char *fmt = nullptr;
+ /* Number of arguments needed by the syntax. */
const int total_args = 0;
- /* Fail to compile by default. */
- const bool is_type_valid = false;
+ /* Whether types of the given arguments are accepted by the syntax above. Fail to compile by
+ * default.
+ */
+ const bool are_types_valid = false;
};
/**
- * Type dependent but always false. Use to add a conditional compile-time error.
+ * Type dependent but always false. Use to add a constexpr-conditional compile-time error.
*/
template<typename T> struct always_false : std::false_type {
};
@@ -118,9 +123,8 @@ constexpr bool is_type_integral = (... && std::is_integral_v<std::decay_t<T>>);
template<typename... T>
constexpr bool is_type_string_related = (... && std::is_constructible_v<std::string, T>);
-template<eFileType filetype, typename... T>
-constexpr std::enable_if_t<filetype == eFileType::OBJ, Formatting<filetype>>
-syntax_elem_to_formatting(const eOBJSyntaxElement key)
+template<typename... T>
+constexpr FormattingSyntax syntax_elem_to_formatting(const eOBJSyntaxElement key)
{
switch (key) {
case eOBJSyntaxElement::vertex_coords: {
@@ -201,9 +205,8 @@ syntax_elem_to_formatting(const eOBJSyntaxElement key)
}
}
-template<eFileType filetype, typename... T>
-constexpr std::enable_if_t<filetype == eFileType::MTL, Formatting<filetype>>
-syntax_elem_to_formatting(const eMTLSyntaxElement key)
+template<typename... T>
+constexpr FormattingSyntax syntax_elem_to_formatting(const eMTLSyntaxElement key)
{
switch (key) {
case eMTLSyntaxElement::newmtl: {
@@ -261,21 +264,25 @@ syntax_elem_to_formatting(const eMTLSyntaxElement key)
}
}
-template<eFileType filetype> class FileHandler : NonCopyable, NonMovable {
+/**
+ * File format and syntax agnostic file writer.
+ */
+template<eFileType filetype> class FormattedFileHandler : NonCopyable, NonMovable {
private:
- FILE *outfile_ = nullptr;
+ std::FILE *outfile_ = nullptr;
std::string outfile_path_;
public:
- FileHandler(std::string outfile_path) noexcept(false) : outfile_path_(std::move(outfile_path))
+ FormattedFileHandler(std::string outfile_path) noexcept(false)
+ : outfile_path_(std::move(outfile_path))
{
outfile_ = std::fopen(outfile_path_.c_str(), "w");
if (!outfile_) {
- throw std::system_error(errno, std::system_category(), "Cannot open file");
+ throw std::system_error(errno, std::system_category(), "Cannot open file " + outfile_path_);
}
}
- ~FileHandler()
+ ~FormattedFileHandler()
{
if (outfile_ && std::fclose(outfile_)) {
std::cerr << "Error: could not close the file '" << outfile_path_
@@ -283,17 +290,24 @@ template<eFileType filetype> class FileHandler : NonCopyable, NonMovable {
}
}
+ /**
+ * Example invocation: `writer->write<eMTLSyntaxElement::newmtl>("foo")`.
+ *
+ * \param key Must match what the instance's filetype expects; i.e., `eMTLSyntaxElement` for
+ * `eFileType::MTL`.
+ */
template<typename FileTypeTraits<filetype>::SyntaxType key, typename... T>
constexpr void write(T &&...args) const
{
- constexpr Formatting<filetype> fmt_nargs_valid = syntax_elem_to_formatting<filetype, T...>(
- key);
- write__impl<fmt_nargs_valid.total_args>(fmt_nargs_valid.fmt, std::forward<T>(args)...);
- /* Types of all arguments and the number of arguments should match
- * what the formatting specifies. */
- return std::enable_if_t < fmt_nargs_valid.is_type_valid &&
- (sizeof...(T) == fmt_nargs_valid.total_args),
- void > ();
+ /* Get format syntax, number of arguments expected and whether types of given arguments are
+ * valid.
+ */
+ constexpr FormattingSyntax fmt_nargs_valid = syntax_elem_to_formatting<T...>(key);
+ BLI_STATIC_ASSERT(fmt_nargs_valid.are_types_valid &&
+ (sizeof...(T) == fmt_nargs_valid.total_args),
+ "Types of all arguments and the number of arguments should match what the "
+ "formatting specifies.");
+ write_impl(fmt_nargs_valid.fmt, std::forward<T>(args)...);
}
private:
@@ -301,11 +315,11 @@ template<eFileType filetype> class FileHandler : NonCopyable, NonMovable {
template<typename T> using remove_cvref_t = std::remove_cv_t<std::remove_reference_t<T>>;
/**
- * Make #std::string etc., usable for `fprintf` family.
+ * Make #std::string etc., usable for `fprintf` family. int float etc. are not affected.
* \return: `const char *` or the original argument if the argument is
* not related to #std::string.
*/
- template<typename T> constexpr auto string_to_primitive(T &&arg) const
+ template<typename T> constexpr auto convert_to_primitive(T &&arg) const
{
if constexpr (std::is_same_v<remove_cvref_t<T>, std::string> ||
std::is_same_v<remove_cvref_t<T>, blender::StringRefNull>) {
@@ -319,21 +333,19 @@ template<eFileType filetype> class FileHandler : NonCopyable, NonMovable {
return;
}
else {
+ /* For int, float etc. */
return std::forward<T>(arg);
}
}
- template<int total_args, typename... T>
- constexpr std::enable_if_t<(total_args != 0), void> write__impl(const char *fmt,
- T &&...args) const
- {
- std::fprintf(outfile_, fmt, string_to_primitive(std::forward<T>(args))...);
- }
- template<int total_args, typename... T>
- constexpr std::enable_if_t<(total_args == 0), void> write__impl(const char *fmt,
- T &&...args) const
+ template<typename... T> constexpr void write_impl(const char *fmt, T &&...args) const
{
- std::fputs(fmt, outfile_);
+ if constexpr (sizeof...(T) == 0) {
+ std::fputs(fmt, outfile_);
+ }
+ else {
+ std::fprintf(outfile_, fmt, convert_to_primitive(std::forward<T>(args))...);
+ }
}
};