Replace ##__VA_ARGS__ with portable TG3__COMMA_VA_ARGS helper (C++17/C++20)

Co-authored-by: syoyo <18676+syoyo@users.noreply.github.com>
Agent-Logs-Url: https://github.com/syoyo/tinygltf/sessions/a7105342-8673-4241-b727-29026461cc67
diff --git a/tiny_gltf_v3.h b/tiny_gltf_v3.h
index 1d100a4..6988f71 100644
--- a/tiny_gltf_v3.h
+++ b/tiny_gltf_v3.h
@@ -2909,6 +2909,22 @@
 }
 
 /* ======================================================================
+ * Internal: Portable variadic-comma helper
+ *
+ * TG3__COMMA_VA_ARGS(__VA_ARGS__) expands to  , __VA_ARGS__  when the
+ * argument list is non-empty, and to nothing when it is empty.
+ *
+ * - C++20 and later: uses the standard __VA_OPT__(,) token.
+ * - C++17 and earlier: falls back to the widely-supported GNU/MSVC
+ *   ##__VA_ARGS__ extension.
+ * ====================================================================== */
+#if __cplusplus >= 202002L
+#  define TG3__COMMA_VA_ARGS(...) __VA_OPT__(,) __VA_ARGS__
+#else
+#  define TG3__COMMA_VA_ARGS(...) , ##__VA_ARGS__
+#endif
+
+/* ======================================================================
  * Internal: Array Parse Macro
  * ====================================================================== */
 
@@ -2923,7 +2939,7 @@
                 if (_items) { \
                     uint32_t _i = 0; \
                     for (auto _it = _arr_it->begin(); _it != _arr_it->end(); ++_it, ++_i) { \
-                        parse_fn((ctx), *_it, &_items[_i], ##__VA_ARGS__); \
+                        parse_fn((ctx), *_it, &_items[_i] TG3__COMMA_VA_ARGS(__VA_ARGS__)); \
                     } \
                     (model_field) = _items; \
                     (count_field) = _count; \
@@ -4094,7 +4110,7 @@
         if ((arr) && (cnt) > 0) { \
             tg3__json jarr; jarr.set_array(); \
             for (uint32_t _i = 0; _i < (cnt); ++_i) { \
-                jarr.push_back(fn(&(arr)[_i], ##__VA_ARGS__)); \
+                jarr.push_back(fn(&(arr)[_i] TG3__COMMA_VA_ARGS(__VA_ARGS__))); \
             } \
             root[key] = static_cast<tg3__json&&>(jarr); \
         }
@@ -4335,7 +4351,7 @@
             w->root[json_key] = static_cast<tg3__json&&>(arr); \
         } \
         w->root[json_key].push_back( \
-            serialize_fn(item, w->options.serialize_defaults, ##__VA_ARGS__)); \
+            serialize_fn(item, w->options.serialize_defaults TG3__COMMA_VA_ARGS(__VA_ARGS__))); \
         return TG3_OK; \
     }