Add alloc functions
diff --git a/doc/changelog.md b/doc/changelog.md
index f5639cd..657defa 100644
--- a/doc/changelog.md
+++ b/doc/changelog.md
@@ -14,6 +14,7 @@
 - Added `std/wbmp`.
 - Added `WUFFS_BASE__PIXEL_BLEND__SRC_OVER`.
 - Added `WUFFS_BASE__PIXEL_FORMAT__BGR_565`.
+- Added alloc functions.
 - Added double-curly blocks.
 - Added interfaces.
 - Added preprocessor.
diff --git a/doc/note/memory-safety.md b/doc/note/memory-safety.md
index fa37b38..2072a74 100644
--- a/doc/note/memory-safety.md
+++ b/doc/note/memory-safety.md
@@ -8,18 +8,20 @@
 additional performance.
 
 A deliberate constraint in the Wuffs language is that struct fields cannot
-store any pointers to dynamically allocated memory, only to e.g. statically
+store any pointers to dynamically allocated memory, only to statically
 allocated error messages (a `base.status`). When a Wuffs decompressor reads
 from or writes to a buffer, that buffer has to be passed on every call, instead
-of e.g. being passed once during initialization and saved to a field. There is
-no ambiguity about whether the caller or callee owns some memory, even when
+of being passed once during initialization and saved to a field. There is no
+ambiguity about whether the caller or callee should free some memory, even when
 encountering an error. It's always caller-owned and callee-borrowed.
 
 Wuffs is also trivially safe against things like memory leaks, use-after-frees
 and double-frees because Wuffs code doesn't even have the *capability* to
-allocate or free memory. Wuffs is certainly less powerful than other
-programming languages, but with less power comes easier proof-of-safety. Still,
-Wuffs is not a toy language and can do [real work](/example).
+allocate or free memory, other than its transpiled-to-C form providing
+`wuffs_foo__bar__alloc` convenience functions to set up before processing a
+single byte of input. Wuffs is certainly less powerful than other programming
+languages, but **with less power comes easier proof of safety**. Still, Wuffs
+is not a toy language and the [example programs](/example) do real work.
 
 Wuffs is a language for writing libraries, and complete programs require
 combining Wuffs with another programming language. The obvious example is the
@@ -56,8 +58,10 @@
 [example/zcat](/example/zcat/zcat.c) program can decompress arbitrarily large
 input using static buffers, without ever calling `malloc`. Indeed, on Linux,
 that program self-imposes a `SECCOMP_MODE_STRICT` sandbox, prohibiting dynamic
-memory allocation (amongst many other useful but dangerous things) at the
-kernel level.
+memory allocation (amongst many other powerful but dangerous things) at the
+kernel level. The [example/jsonptr](/example/jsonptr/jsonptr.cc) program, which
+parses and filters [JSON](https://www.json.org/), is another example that does
+useful work within a strict sandbox.
 
 
 ## Thread-Safety
diff --git a/example/library/library.c b/example/library/library.c
index 78cab0f..d705cdd 100644
--- a/example/library/library.c
+++ b/example/library/library.c
@@ -33,7 +33,6 @@
 */
 
 #include <stdio.h>
-#include <stdlib.h>
 
 // Wuffs ships as a "single file C library" or "header file library" as per
 // https://github.com/nothings/stb/blob/master/docs/stb_howto.txt
@@ -59,7 +58,7 @@
 //
 // Passing --no-name to the gzip command line also means to skip the timestamp,
 // which means that its output is deterministic.
-uint8_t g_src_ptr[] = {
+uint8_t g_src_array[] = {
     0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,  // 00..07
     0x00, 0x03, 0xf3, 0x48, 0xcd, 0xc9, 0xc9, 0x57,  // 08..0F
     0x08, 0x2f, 0x4d, 0x4b, 0x2b, 0xd6, 0xe3, 0x02,  // 10..17
@@ -79,43 +78,28 @@
 
 static const char*  //
 decode() {
-  wuffs_base__io_buffer dst;
-  dst.data.ptr = g_dst_buffer_array;
-  dst.data.len = DST_BUFFER_ARRAY_SIZE;
-  dst.meta.wi = 0;
-  dst.meta.ri = 0;
-  dst.meta.pos = 0;
-  dst.meta.closed = false;
-
-  wuffs_base__io_buffer src;
-  src.data.ptr = g_src_ptr;
-  src.data.len = g_src_len;
-  src.meta.wi = g_src_len;
-  src.meta.ri = 0;
-  src.meta.pos = 0;
-  src.meta.closed = true;
-
-  wuffs_gzip__decoder* dec =
-      (wuffs_gzip__decoder*)(calloc(sizeof__wuffs_gzip__decoder(), 1));
+  wuffs_gzip__decoder* dec = wuffs_gzip__decoder__alloc();
   if (!dec) {
     return "out of memory";
   }
-  wuffs_base__status status = wuffs_gzip__decoder__initialize(
-      dec, sizeof__wuffs_gzip__decoder(), WUFFS_VERSION,
-      WUFFS_INITIALIZE__ALREADY_ZEROED);
-  if (!wuffs_base__status__is_ok(&status)) {
-    free(dec);
-    return wuffs_base__status__message(&status);
-  }
-  status = wuffs_gzip__decoder__transform_io(
+
+  wuffs_base__io_buffer dst =
+      wuffs_base__ptr_u8__writer(&g_dst_buffer_array[0], DST_BUFFER_ARRAY_SIZE);
+
+  static const bool closed = true;
+  wuffs_base__io_buffer src =
+      wuffs_base__ptr_u8__reader(&g_src_array[0], g_src_len, closed);
+
+  wuffs_base__status status = wuffs_gzip__decoder__transform_io(
       dec, &dst, &src,
-      wuffs_base__make_slice_u8(g_work_buffer_array, WORK_BUFFER_ARRAY_SIZE));
+      wuffs_base__make_slice_u8(&g_work_buffer_array[0],
+                                WORK_BUFFER_ARRAY_SIZE));
+  free(dec);
+
   if (!wuffs_base__status__is_ok(&status)) {
-    free(dec);
     return wuffs_base__status__message(&status);
   }
   fwrite(dst.data.ptr, sizeof(uint8_t), dst.meta.wi, stdout);
-  free(dec);
   return NULL;
 }
 
diff --git a/internal/cgen/base/all-impl.c b/internal/cgen/base/all-impl.c
index 405e963..0ba6e6e 100644
--- a/internal/cgen/base/all-impl.c
+++ b/internal/cgen/base/all-impl.c
@@ -28,9 +28,16 @@
 
 #include <stdbool.h>
 #include <stdint.h>
+#include <stdlib.h>
 #include <string.h>
 
 #ifdef __cplusplus
+#if __cplusplus >= 201103L
+#include <memory>
+#else
+#warning "Wuffs' C++ code requires -std=c++11 or later"
+#endif
+
 extern "C" {
 #endif
 
diff --git a/internal/cgen/cgen.go b/internal/cgen/cgen.go
index b186f97..319bdd3 100644
--- a/internal/cgen/cgen.go
+++ b/internal/cgen/cgen.go
@@ -385,7 +385,11 @@
 		buf.writes("wuffs_base__vtable first_vtable;\n")
 		buf.writes("} private_impl;\n\n")
 
-		buf.writes("\n#ifdef __cplusplus\n\n")
+		buf.writes("\n#ifdef __cplusplus\n")
+		buf.writes("#if __cplusplus >= 201103L\n")
+		buf.printf("using unique_ptr = std::unique_ptr<wuffs_base__%s, decltype(&free)>;", n)
+		buf.writes("#endif\n\n")
+
 		for _, f := range builtInInterfaceMethods[qid] {
 			if err := g.writeFuncSignature(buf, f, wfsCppDecl); err != nil {
 				return err
@@ -681,13 +685,40 @@
 		}
 	}
 
+	b.writes("// ---------------- Allocs\n\n")
+
+	b.writes("// These functions allocate and initialize Wuffs structs. They return NULL if\n")
+	b.writes("// memory allocation fails. If they return non-NULL, there is no need to call\n")
+	b.writes("// wuffs_foo__bar__initialize, but the caller is responsible for eventually\n")
+	b.writes("// calling free on the returned pointer. That pointer is effectively a C++\n")
+	b.writes("// std::unique_ptr<T, decltype(&free)>.\n\n")
+
+	for _, n := range g.structList {
+		if !n.Public() {
+			continue
+		}
+		if err := g.writeAllocSignature(b, n); err != nil {
+			return err
+		}
+		b.writes(";\n\n")
+		structName := n.QID().Str(g.tm)
+		for _, impl := range n.Implements() {
+			iQID := impl.AsTypeExpr().QID()
+			iName := fmt.Sprintf("wuffs_%s__%s", iQID[0].Str(g.tm), iQID[1].Str(g.tm))
+			b.printf("static inline %s*  //\n", iName)
+			b.printf("%s%s__alloc_as__%s(){\n", g.pkgPrefix, structName, iName)
+			b.printf("return (%s*)(%s%s__alloc());\n", iName, g.pkgPrefix, structName)
+			b.printf("}\n\n")
+		}
+	}
+
 	b.writes("// ---------------- Upcasts\n\n")
 	for _, n := range g.structList {
 		structName := n.QID().Str(g.tm)
 		for _, impl := range n.Implements() {
 			iQID := impl.AsTypeExpr().QID()
 			iName := fmt.Sprintf("wuffs_%s__%s", iQID[0].Str(g.tm), iQID[1].Str(g.tm))
-			b.printf("static inline %s* //\n", iName)
+			b.printf("static inline %s*  //\n", iName)
 			b.printf("%s%s__upcast_as__%s(%s%s* p){\n",
 				g.pkgPrefix, structName, iName, g.pkgPrefix, structName)
 			b.printf("return (%s*)p;\n", iName)
@@ -1086,6 +1117,24 @@
 	fullStructName := g.pkgPrefix + structName + "__struct"
 	b.writes("#ifdef __cplusplus\n")
 
+	b.writes("#if __cplusplus >= 201103L\n")
+	b.printf("using unique_ptr = std::unique_ptr<%s%s, decltype(&free)>;\n\n", g.pkgPrefix, structName)
+	b.writes("// On failure, the alloc_etc functions return nullptr. They don't throw.\n\n")
+	b.writes("static inline unique_ptr  //\n")
+	b.writes("alloc() {\n")
+	b.printf("return unique_ptr(%s%s__alloc(), &free);\n", g.pkgPrefix, structName)
+	b.writes("}\n")
+	for _, impl := range n.Implements() {
+		iQID := impl.AsTypeExpr().QID()
+		iName := fmt.Sprintf("wuffs_%s__%s", iQID[0].Str(g.tm), iQID[1].Str(g.tm))
+		b.printf("\nstatic inline %s::unique_ptr  //\n", iName)
+		b.printf("alloc_as__%s(){\n", iName)
+		b.printf("return %s::unique_ptr(%s%s__alloc_as__%s(), &free);\n",
+			iName, g.pkgPrefix, structName, iName)
+		b.printf("}\n")
+	}
+	b.writes("#endif  // __cplusplus >= 201103L\n\n")
+
 	b.writes("#if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)\n")
 	b.writes("// Disallow constructing or copying an object via standard C++ mechanisms,\n")
 	b.writes("// e.g. the \"new\" operator, as this struct is intentionally opaque. Its total\n")
@@ -1115,7 +1164,7 @@
 
 	// The empty // comment makes clang-format place the function name
 	// at the start of a line.
-	b.writes("inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT //\n" +
+	b.writes("inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT  //\n" +
 		"initialize(size_t sizeof_star_self, uint64_t wuffs_version, uint32_t initialize_flags) {\n")
 	b.printf("return %s%s__initialize(this, sizeof_star_self, wuffs_version, initialize_flags);\n}\n\n",
 		g.pkgPrefix, structName)
@@ -1123,7 +1172,7 @@
 	for _, impl := range n.Implements() {
 		iQID := impl.AsTypeExpr().QID()
 		iName := fmt.Sprintf("wuffs_%s__%s", iQID[0].Str(g.tm), iQID[1].Str(g.tm))
-		b.printf("inline %s* //\n", iName)
+		b.printf("inline %s*  //\n", iName)
 		b.printf("upcast_as__%s(){\n", iName)
 		b.printf("return (%s*)this;\n", iName)
 		b.printf("}\n\n")
@@ -1201,14 +1250,21 @@
 
 func (g *gen) writeInitializerSignature(b *buffer, n *a.Struct, public bool) error {
 	structName := n.QID().Str(g.tm)
-	b.printf("wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT //\n"+
+	b.printf("wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT  //\n"+
 		"%s%s__initialize(%s%s *self, size_t sizeof_star_self, uint64_t wuffs_version, uint32_t initialize_flags)",
 		g.pkgPrefix, structName, g.pkgPrefix, structName)
 	return nil
 }
 
+func (g *gen) writeAllocSignature(b *buffer, n *a.Struct) error {
+	structName := n.QID().Str(g.tm)
+	b.printf("%s%s*  //\n%s%s__alloc()", g.pkgPrefix, structName, g.pkgPrefix, structName)
+	return nil
+}
+
 func (g *gen) writeSizeofSignature(b *buffer, n *a.Struct) error {
-	b.printf("size_t //\nsizeof__%s%s()", g.pkgPrefix, n.QID().Str(g.tm))
+	structName := n.QID().Str(g.tm)
+	b.printf("size_t  //\nsizeof__%s%s()", g.pkgPrefix, structName)
 	return nil
 }
 
@@ -1314,10 +1370,25 @@
 	b.writes("}\n\n")
 
 	if n.Public() {
+		structName := n.QID().Str(g.tm)
+		if err := g.writeAllocSignature(b, n); err != nil {
+			return err
+		}
+		b.writes("{\n")
+		b.printf("%s%s* x = (%s%s*)(calloc(sizeof(%s%s), 1));\n",
+			g.pkgPrefix, structName, g.pkgPrefix, structName, g.pkgPrefix, structName)
+		b.writes("if (!x) { return NULL; }\n")
+		b.printf("if (%s%s__initialize(x, sizeof(%s%s), "+
+			"WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {\n",
+			g.pkgPrefix, structName, g.pkgPrefix, structName)
+		b.writes("free(x); return NULL; }\n")
+		b.writes("return x;\n")
+		b.writes("}\n\n")
+
 		if err := g.writeSizeofSignature(b, n); err != nil {
 			return err
 		}
-		b.printf("{ return sizeof (%s%s); }\n\n", g.pkgPrefix, n.QID().Str(g.tm))
+		b.printf("{ return sizeof(%s%s); }\n\n", g.pkgPrefix, structName)
 	}
 	return nil
 }
diff --git a/internal/cgen/data.go b/internal/cgen/data.go
index 82a3973..3d51198 100644
--- a/internal/cgen/data.go
+++ b/internal/cgen/data.go
@@ -17,7 +17,7 @@
 package cgen
 
 const baseAllImplC = "" +
-	"#ifndef WUFFS_INCLUDE_GUARD__BASE\n#define WUFFS_INCLUDE_GUARD__BASE\n\n#if defined(WUFFS_IMPLEMENTATION) && !defined(WUFFS_CONFIG__MODULES)\n#define WUFFS_CONFIG__MODULES\n#define WUFFS_CONFIG__MODULE__BASE\n#endif\n\n// !! WUFFS MONOLITHIC RELEASE DISCARDS EVERYTHING ABOVE.\n\n// !! INSERT base/copyright\n\n#include <stdbool.h>\n#include <stdint.h>\n#include <string.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n// !! INSERT base/all-public.h.\n\n// !! INSERT InterfaceDeclarations.\n\n" +
+	"#ifndef WUFFS_INCLUDE_GUARD__BASE\n#define WUFFS_INCLUDE_GUARD__BASE\n\n#if defined(WUFFS_IMPLEMENTATION) && !defined(WUFFS_CONFIG__MODULES)\n#define WUFFS_CONFIG__MODULES\n#define WUFFS_CONFIG__MODULE__BASE\n#endif\n\n// !! WUFFS MONOLITHIC RELEASE DISCARDS EVERYTHING ABOVE.\n\n// !! INSERT base/copyright\n\n#include <stdbool.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <string.h>\n\n#ifdef __cplusplus\n#if __cplusplus >= 201103L\n#include <memory>\n#else\n#warning \"Wuffs' C++ code requires -std=c++11 or later\"\n#endif\n\nextern \"C\" {\n#endif\n\n// !! INSERT base/all-public.h.\n\n// !! INSERT InterfaceDeclarations.\n\n" +
 	"" +
 	"// ----------------\n\n#ifdef __cplusplus\n}  // extern \"C\"\n#endif\n\n// WUFFS C HEADER ENDS HERE.\n#ifdef WUFFS_IMPLEMENTATION\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n// !! INSERT base/all-private.h.\n\n" +
 	"" +
diff --git a/release/c/wuffs-unsupported-snapshot.c b/release/c/wuffs-unsupported-snapshot.c
index ed2198f..50346ab 100644
--- a/release/c/wuffs-unsupported-snapshot.c
+++ b/release/c/wuffs-unsupported-snapshot.c
@@ -32,9 +32,16 @@
 
 #include <stdbool.h>
 #include <stdint.h>
+#include <stdlib.h>
 #include <string.h>
 
 #ifdef __cplusplus
+#if __cplusplus >= 201103L
+#include <memory>
+#else
+#warning "Wuffs' C++ code requires -std=c++11 or later"
+#endif
+
 extern "C" {
 #endif
 
@@ -3839,6 +3846,9 @@
   } private_impl;
 
 #ifdef __cplusplus
+#if __cplusplus >= 201103L
+  using unique_ptr = std::unique_ptr<wuffs_base__hasher_u32, decltype(&free)>;
+#endif
 
   inline uint32_t  //
   update_u32(wuffs_base__slice_u8 a_x) {
@@ -3957,6 +3967,10 @@
   } private_impl;
 
 #ifdef __cplusplus
+#if __cplusplus >= 201103L
+  using unique_ptr =
+      std::unique_ptr<wuffs_base__image_decoder, decltype(&free)>;
+#endif
 
   inline wuffs_base__status  //
   ack_metadata_chunk(wuffs_base__io_buffer* a_src) {
@@ -4071,6 +4085,10 @@
   } private_impl;
 
 #ifdef __cplusplus
+#if __cplusplus >= 201103L
+  using unique_ptr =
+      std::unique_ptr<wuffs_base__io_transformer, decltype(&free)>;
+#endif
 
   inline wuffs_base__status  //
   transform_io(wuffs_base__io_buffer* a_dst,
@@ -4124,6 +4142,10 @@
   } private_impl;
 
 #ifdef __cplusplus
+#if __cplusplus >= 201103L
+  using unique_ptr =
+      std::unique_ptr<wuffs_base__token_decoder, decltype(&free)>;
+#endif
 
   inline wuffs_base__status  //
   decode_tokens(wuffs_base__token_buffer* a_dst,
@@ -4179,6 +4201,22 @@
 size_t  //
 sizeof__wuffs_adler32__hasher();
 
+// ---------------- Allocs
+
+// These functions allocate and initialize Wuffs structs. They return NULL if
+// memory allocation fails. If they return non-NULL, there is no need to call
+// wuffs_foo__bar__initialize, but the caller is responsible for eventually
+// calling free on the returned pointer. That pointer is effectively a C++
+// std::unique_ptr<T, decltype(&free)>.
+
+wuffs_adler32__hasher*  //
+wuffs_adler32__hasher__alloc();
+
+static inline wuffs_base__hasher_u32*  //
+wuffs_adler32__hasher__alloc_as__wuffs_base__hasher_u32() {
+  return (wuffs_base__hasher_u32*)(wuffs_adler32__hasher__alloc());
+}
+
 // ---------------- Upcasts
 
 static inline wuffs_base__hasher_u32*  //
@@ -4222,6 +4260,23 @@
   } private_impl;
 
 #ifdef __cplusplus
+#if __cplusplus >= 201103L
+  using unique_ptr = std::unique_ptr<wuffs_adler32__hasher, decltype(&free)>;
+
+  // On failure, the alloc_etc functions return nullptr. They don't throw.
+
+  static inline unique_ptr  //
+  alloc() {
+    return unique_ptr(wuffs_adler32__hasher__alloc(), &free);
+  }
+
+  static inline wuffs_base__hasher_u32::unique_ptr  //
+  alloc_as__wuffs_base__hasher_u32() {
+    return wuffs_base__hasher_u32::unique_ptr(
+        wuffs_adler32__hasher__alloc_as__wuffs_base__hasher_u32(), &free);
+  }
+#endif  // __cplusplus >= 201103L
+
 #if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
   // Disallow constructing or copying an object via standard C++ mechanisms,
   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
@@ -4312,6 +4367,22 @@
 size_t  //
 sizeof__wuffs_bmp__decoder();
 
+// ---------------- Allocs
+
+// These functions allocate and initialize Wuffs structs. They return NULL if
+// memory allocation fails. If they return non-NULL, there is no need to call
+// wuffs_foo__bar__initialize, but the caller is responsible for eventually
+// calling free on the returned pointer. That pointer is effectively a C++
+// std::unique_ptr<T, decltype(&free)>.
+
+wuffs_bmp__decoder*  //
+wuffs_bmp__decoder__alloc();
+
+static inline wuffs_base__image_decoder*  //
+wuffs_bmp__decoder__alloc_as__wuffs_base__image_decoder() {
+  return (wuffs_base__image_decoder*)(wuffs_bmp__decoder__alloc());
+}
+
 // ---------------- Upcasts
 
 static inline wuffs_base__image_decoder*  //
@@ -4444,6 +4515,23 @@
   } private_data;
 
 #ifdef __cplusplus
+#if __cplusplus >= 201103L
+  using unique_ptr = std::unique_ptr<wuffs_bmp__decoder, decltype(&free)>;
+
+  // On failure, the alloc_etc functions return nullptr. They don't throw.
+
+  static inline unique_ptr  //
+  alloc() {
+    return unique_ptr(wuffs_bmp__decoder__alloc(), &free);
+  }
+
+  static inline wuffs_base__image_decoder::unique_ptr  //
+  alloc_as__wuffs_base__image_decoder() {
+    return wuffs_base__image_decoder::unique_ptr(
+        wuffs_bmp__decoder__alloc_as__wuffs_base__image_decoder(), &free);
+  }
+#endif  // __cplusplus >= 201103L
+
 #if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
   // Disallow constructing or copying an object via standard C++ mechanisms,
   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
@@ -4596,6 +4684,22 @@
 size_t  //
 sizeof__wuffs_crc32__ieee_hasher();
 
+// ---------------- Allocs
+
+// These functions allocate and initialize Wuffs structs. They return NULL if
+// memory allocation fails. If they return non-NULL, there is no need to call
+// wuffs_foo__bar__initialize, but the caller is responsible for eventually
+// calling free on the returned pointer. That pointer is effectively a C++
+// std::unique_ptr<T, decltype(&free)>.
+
+wuffs_crc32__ieee_hasher*  //
+wuffs_crc32__ieee_hasher__alloc();
+
+static inline wuffs_base__hasher_u32*  //
+wuffs_crc32__ieee_hasher__alloc_as__wuffs_base__hasher_u32() {
+  return (wuffs_base__hasher_u32*)(wuffs_crc32__ieee_hasher__alloc());
+}
+
 // ---------------- Upcasts
 
 static inline wuffs_base__hasher_u32*  //
@@ -4638,6 +4742,23 @@
   } private_impl;
 
 #ifdef __cplusplus
+#if __cplusplus >= 201103L
+  using unique_ptr = std::unique_ptr<wuffs_crc32__ieee_hasher, decltype(&free)>;
+
+  // On failure, the alloc_etc functions return nullptr. They don't throw.
+
+  static inline unique_ptr  //
+  alloc() {
+    return unique_ptr(wuffs_crc32__ieee_hasher__alloc(), &free);
+  }
+
+  static inline wuffs_base__hasher_u32::unique_ptr  //
+  alloc_as__wuffs_base__hasher_u32() {
+    return wuffs_base__hasher_u32::unique_ptr(
+        wuffs_crc32__ieee_hasher__alloc_as__wuffs_base__hasher_u32(), &free);
+  }
+#endif  // __cplusplus >= 201103L
+
 #if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
   // Disallow constructing or copying an object via standard C++ mechanisms,
   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
@@ -4740,6 +4861,22 @@
 size_t  //
 sizeof__wuffs_deflate__decoder();
 
+// ---------------- Allocs
+
+// These functions allocate and initialize Wuffs structs. They return NULL if
+// memory allocation fails. If they return non-NULL, there is no need to call
+// wuffs_foo__bar__initialize, but the caller is responsible for eventually
+// calling free on the returned pointer. That pointer is effectively a C++
+// std::unique_ptr<T, decltype(&free)>.
+
+wuffs_deflate__decoder*  //
+wuffs_deflate__decoder__alloc();
+
+static inline wuffs_base__io_transformer*  //
+wuffs_deflate__decoder__alloc_as__wuffs_base__io_transformer() {
+  return (wuffs_base__io_transformer*)(wuffs_deflate__decoder__alloc());
+}
+
 // ---------------- Upcasts
 
 static inline wuffs_base__io_transformer*  //
@@ -4842,6 +4979,23 @@
   } private_data;
 
 #ifdef __cplusplus
+#if __cplusplus >= 201103L
+  using unique_ptr = std::unique_ptr<wuffs_deflate__decoder, decltype(&free)>;
+
+  // On failure, the alloc_etc functions return nullptr. They don't throw.
+
+  static inline unique_ptr  //
+  alloc() {
+    return unique_ptr(wuffs_deflate__decoder__alloc(), &free);
+  }
+
+  static inline wuffs_base__io_transformer::unique_ptr  //
+  alloc_as__wuffs_base__io_transformer() {
+    return wuffs_base__io_transformer::unique_ptr(
+        wuffs_deflate__decoder__alloc_as__wuffs_base__io_transformer(), &free);
+  }
+#endif  // __cplusplus >= 201103L
+
 #if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
   // Disallow constructing or copying an object via standard C++ mechanisms,
   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
@@ -4944,6 +5098,22 @@
 size_t  //
 sizeof__wuffs_lzw__decoder();
 
+// ---------------- Allocs
+
+// These functions allocate and initialize Wuffs structs. They return NULL if
+// memory allocation fails. If they return non-NULL, there is no need to call
+// wuffs_foo__bar__initialize, but the caller is responsible for eventually
+// calling free on the returned pointer. That pointer is effectively a C++
+// std::unique_ptr<T, decltype(&free)>.
+
+wuffs_lzw__decoder*  //
+wuffs_lzw__decoder__alloc();
+
+static inline wuffs_base__io_transformer*  //
+wuffs_lzw__decoder__alloc_as__wuffs_base__io_transformer() {
+  return (wuffs_base__io_transformer*)(wuffs_lzw__decoder__alloc());
+}
+
 // ---------------- Upcasts
 
 static inline wuffs_base__io_transformer*  //
@@ -5018,6 +5188,23 @@
   } private_data;
 
 #ifdef __cplusplus
+#if __cplusplus >= 201103L
+  using unique_ptr = std::unique_ptr<wuffs_lzw__decoder, decltype(&free)>;
+
+  // On failure, the alloc_etc functions return nullptr. They don't throw.
+
+  static inline unique_ptr  //
+  alloc() {
+    return unique_ptr(wuffs_lzw__decoder__alloc(), &free);
+  }
+
+  static inline wuffs_base__io_transformer::unique_ptr  //
+  alloc_as__wuffs_base__io_transformer() {
+    return wuffs_base__io_transformer::unique_ptr(
+        wuffs_lzw__decoder__alloc_as__wuffs_base__io_transformer(), &free);
+  }
+#endif  // __cplusplus >= 201103L
+
 #if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
   // Disallow constructing or copying an object via standard C++ mechanisms,
   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
@@ -5156,6 +5343,30 @@
 size_t  //
 sizeof__wuffs_gif__decoder();
 
+// ---------------- Allocs
+
+// These functions allocate and initialize Wuffs structs. They return NULL if
+// memory allocation fails. If they return non-NULL, there is no need to call
+// wuffs_foo__bar__initialize, but the caller is responsible for eventually
+// calling free on the returned pointer. That pointer is effectively a C++
+// std::unique_ptr<T, decltype(&free)>.
+
+wuffs_gif__config_decoder*  //
+wuffs_gif__config_decoder__alloc();
+
+static inline wuffs_base__image_decoder*  //
+wuffs_gif__config_decoder__alloc_as__wuffs_base__image_decoder() {
+  return (wuffs_base__image_decoder*)(wuffs_gif__config_decoder__alloc());
+}
+
+wuffs_gif__decoder*  //
+wuffs_gif__decoder__alloc();
+
+static inline wuffs_base__image_decoder*  //
+wuffs_gif__decoder__alloc_as__wuffs_base__image_decoder() {
+  return (wuffs_base__image_decoder*)(wuffs_gif__decoder__alloc());
+}
+
 // ---------------- Upcasts
 
 static inline wuffs_base__image_decoder*  //
@@ -5410,6 +5621,25 @@
   } private_data;
 
 #ifdef __cplusplus
+#if __cplusplus >= 201103L
+  using unique_ptr =
+      std::unique_ptr<wuffs_gif__config_decoder, decltype(&free)>;
+
+  // On failure, the alloc_etc functions return nullptr. They don't throw.
+
+  static inline unique_ptr  //
+  alloc() {
+    return unique_ptr(wuffs_gif__config_decoder__alloc(), &free);
+  }
+
+  static inline wuffs_base__image_decoder::unique_ptr  //
+  alloc_as__wuffs_base__image_decoder() {
+    return wuffs_base__image_decoder::unique_ptr(
+        wuffs_gif__config_decoder__alloc_as__wuffs_base__image_decoder(),
+        &free);
+  }
+#endif  // __cplusplus >= 201103L
+
 #if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
   // Disallow constructing or copying an object via standard C++ mechanisms,
   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
@@ -5666,6 +5896,23 @@
   } private_data;
 
 #ifdef __cplusplus
+#if __cplusplus >= 201103L
+  using unique_ptr = std::unique_ptr<wuffs_gif__decoder, decltype(&free)>;
+
+  // On failure, the alloc_etc functions return nullptr. They don't throw.
+
+  static inline unique_ptr  //
+  alloc() {
+    return unique_ptr(wuffs_gif__decoder__alloc(), &free);
+  }
+
+  static inline wuffs_base__image_decoder::unique_ptr  //
+  alloc_as__wuffs_base__image_decoder() {
+    return wuffs_base__image_decoder::unique_ptr(
+        wuffs_gif__decoder__alloc_as__wuffs_base__image_decoder(), &free);
+  }
+#endif  // __cplusplus >= 201103L
+
 #if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
   // Disallow constructing or copying an object via standard C++ mechanisms,
   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
@@ -5830,6 +6077,22 @@
 size_t  //
 sizeof__wuffs_gzip__decoder();
 
+// ---------------- Allocs
+
+// These functions allocate and initialize Wuffs structs. They return NULL if
+// memory allocation fails. If they return non-NULL, there is no need to call
+// wuffs_foo__bar__initialize, but the caller is responsible for eventually
+// calling free on the returned pointer. That pointer is effectively a C++
+// std::unique_ptr<T, decltype(&free)>.
+
+wuffs_gzip__decoder*  //
+wuffs_gzip__decoder__alloc();
+
+static inline wuffs_base__io_transformer*  //
+wuffs_gzip__decoder__alloc_as__wuffs_base__io_transformer() {
+  return (wuffs_base__io_transformer*)(wuffs_gzip__decoder__alloc());
+}
+
 // ---------------- Upcasts
 
 static inline wuffs_base__io_transformer*  //
@@ -5894,6 +6157,23 @@
   } private_data;
 
 #ifdef __cplusplus
+#if __cplusplus >= 201103L
+  using unique_ptr = std::unique_ptr<wuffs_gzip__decoder, decltype(&free)>;
+
+  // On failure, the alloc_etc functions return nullptr. They don't throw.
+
+  static inline unique_ptr  //
+  alloc() {
+    return unique_ptr(wuffs_gzip__decoder__alloc(), &free);
+  }
+
+  static inline wuffs_base__io_transformer::unique_ptr  //
+  alloc_as__wuffs_base__io_transformer() {
+    return wuffs_base__io_transformer::unique_ptr(
+        wuffs_gzip__decoder__alloc_as__wuffs_base__io_transformer(), &free);
+  }
+#endif  // __cplusplus >= 201103L
+
 #if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
   // Disallow constructing or copying an object via standard C++ mechanisms,
   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
@@ -6042,6 +6322,22 @@
 size_t  //
 sizeof__wuffs_json__decoder();
 
+// ---------------- Allocs
+
+// These functions allocate and initialize Wuffs structs. They return NULL if
+// memory allocation fails. If they return non-NULL, there is no need to call
+// wuffs_foo__bar__initialize, but the caller is responsible for eventually
+// calling free on the returned pointer. That pointer is effectively a C++
+// std::unique_ptr<T, decltype(&free)>.
+
+wuffs_json__decoder*  //
+wuffs_json__decoder__alloc();
+
+static inline wuffs_base__token_decoder*  //
+wuffs_json__decoder__alloc_as__wuffs_base__token_decoder() {
+  return (wuffs_base__token_decoder*)(wuffs_json__decoder__alloc());
+}
+
 // ---------------- Upcasts
 
 static inline wuffs_base__token_decoder*  //
@@ -6126,6 +6422,23 @@
   } private_data;
 
 #ifdef __cplusplus
+#if __cplusplus >= 201103L
+  using unique_ptr = std::unique_ptr<wuffs_json__decoder, decltype(&free)>;
+
+  // On failure, the alloc_etc functions return nullptr. They don't throw.
+
+  static inline unique_ptr  //
+  alloc() {
+    return unique_ptr(wuffs_json__decoder__alloc(), &free);
+  }
+
+  static inline wuffs_base__token_decoder::unique_ptr  //
+  alloc_as__wuffs_base__token_decoder() {
+    return wuffs_base__token_decoder::unique_ptr(
+        wuffs_json__decoder__alloc_as__wuffs_base__token_decoder(), &free);
+  }
+#endif  // __cplusplus >= 201103L
+
 #if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
   // Disallow constructing or copying an object via standard C++ mechanisms,
   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
@@ -6227,6 +6540,22 @@
 size_t  //
 sizeof__wuffs_wbmp__decoder();
 
+// ---------------- Allocs
+
+// These functions allocate and initialize Wuffs structs. They return NULL if
+// memory allocation fails. If they return non-NULL, there is no need to call
+// wuffs_foo__bar__initialize, but the caller is responsible for eventually
+// calling free on the returned pointer. That pointer is effectively a C++
+// std::unique_ptr<T, decltype(&free)>.
+
+wuffs_wbmp__decoder*  //
+wuffs_wbmp__decoder__alloc();
+
+static inline wuffs_base__image_decoder*  //
+wuffs_wbmp__decoder__alloc_as__wuffs_base__image_decoder() {
+  return (wuffs_base__image_decoder*)(wuffs_wbmp__decoder__alloc());
+}
+
 // ---------------- Upcasts
 
 static inline wuffs_base__image_decoder*  //
@@ -6342,6 +6671,23 @@
   } private_data;
 
 #ifdef __cplusplus
+#if __cplusplus >= 201103L
+  using unique_ptr = std::unique_ptr<wuffs_wbmp__decoder, decltype(&free)>;
+
+  // On failure, the alloc_etc functions return nullptr. They don't throw.
+
+  static inline unique_ptr  //
+  alloc() {
+    return unique_ptr(wuffs_wbmp__decoder__alloc(), &free);
+  }
+
+  static inline wuffs_base__image_decoder::unique_ptr  //
+  alloc_as__wuffs_base__image_decoder() {
+    return wuffs_base__image_decoder::unique_ptr(
+        wuffs_wbmp__decoder__alloc_as__wuffs_base__image_decoder(), &free);
+  }
+#endif  // __cplusplus >= 201103L
+
 #if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
   // Disallow constructing or copying an object via standard C++ mechanisms,
   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
@@ -6503,6 +6849,22 @@
 size_t  //
 sizeof__wuffs_zlib__decoder();
 
+// ---------------- Allocs
+
+// These functions allocate and initialize Wuffs structs. They return NULL if
+// memory allocation fails. If they return non-NULL, there is no need to call
+// wuffs_foo__bar__initialize, but the caller is responsible for eventually
+// calling free on the returned pointer. That pointer is effectively a C++
+// std::unique_ptr<T, decltype(&free)>.
+
+wuffs_zlib__decoder*  //
+wuffs_zlib__decoder__alloc();
+
+static inline wuffs_base__io_transformer*  //
+wuffs_zlib__decoder__alloc_as__wuffs_base__io_transformer() {
+  return (wuffs_base__io_transformer*)(wuffs_zlib__decoder__alloc());
+}
+
 // ---------------- Upcasts
 
 static inline wuffs_base__io_transformer*  //
@@ -6578,6 +6940,23 @@
   } private_data;
 
 #ifdef __cplusplus
+#if __cplusplus >= 201103L
+  using unique_ptr = std::unique_ptr<wuffs_zlib__decoder, decltype(&free)>;
+
+  // On failure, the alloc_etc functions return nullptr. They don't throw.
+
+  static inline unique_ptr  //
+  alloc() {
+    return unique_ptr(wuffs_zlib__decoder__alloc(), &free);
+  }
+
+  static inline wuffs_base__io_transformer::unique_ptr  //
+  alloc_as__wuffs_base__io_transformer() {
+    return wuffs_base__io_transformer::unique_ptr(
+        wuffs_zlib__decoder__alloc_as__wuffs_base__io_transformer(), &free);
+  }
+#endif  // __cplusplus >= 201103L
+
 #if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
   // Disallow constructing or copying an object via standard C++ mechanisms,
   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
@@ -10529,6 +10908,23 @@
   return wuffs_base__make_status(NULL);
 }
 
+wuffs_adler32__hasher*  //
+wuffs_adler32__hasher__alloc() {
+  wuffs_adler32__hasher* x =
+      (wuffs_adler32__hasher*)(calloc(sizeof(wuffs_adler32__hasher), 1));
+  if (!x) {
+    return NULL;
+  }
+  if (wuffs_adler32__hasher__initialize(x, sizeof(wuffs_adler32__hasher),
+                                        WUFFS_VERSION,
+                                        WUFFS_INITIALIZE__ALREADY_ZEROED)
+          .repr) {
+    free(x);
+    return NULL;
+  }
+  return x;
+}
+
 size_t  //
 sizeof__wuffs_adler32__hasher() {
   return sizeof(wuffs_adler32__hasher);
@@ -10727,6 +11123,23 @@
   return wuffs_base__make_status(NULL);
 }
 
+wuffs_bmp__decoder*  //
+wuffs_bmp__decoder__alloc() {
+  wuffs_bmp__decoder* x =
+      (wuffs_bmp__decoder*)(calloc(sizeof(wuffs_bmp__decoder), 1));
+  if (!x) {
+    return NULL;
+  }
+  if (wuffs_bmp__decoder__initialize(x, sizeof(wuffs_bmp__decoder),
+                                     WUFFS_VERSION,
+                                     WUFFS_INITIALIZE__ALREADY_ZEROED)
+          .repr) {
+    free(x);
+    return NULL;
+  }
+  return x;
+}
+
 size_t  //
 sizeof__wuffs_bmp__decoder() {
   return sizeof(wuffs_bmp__decoder);
@@ -12927,6 +13340,23 @@
   return wuffs_base__make_status(NULL);
 }
 
+wuffs_crc32__ieee_hasher*  //
+wuffs_crc32__ieee_hasher__alloc() {
+  wuffs_crc32__ieee_hasher* x =
+      (wuffs_crc32__ieee_hasher*)(calloc(sizeof(wuffs_crc32__ieee_hasher), 1));
+  if (!x) {
+    return NULL;
+  }
+  if (wuffs_crc32__ieee_hasher__initialize(x, sizeof(wuffs_crc32__ieee_hasher),
+                                           WUFFS_VERSION,
+                                           WUFFS_INITIALIZE__ALREADY_ZEROED)
+          .repr) {
+    free(x);
+    return NULL;
+  }
+  return x;
+}
+
 size_t  //
 sizeof__wuffs_crc32__ieee_hasher() {
   return sizeof(wuffs_crc32__ieee_hasher);
@@ -13234,6 +13664,23 @@
   return wuffs_base__make_status(NULL);
 }
 
+wuffs_deflate__decoder*  //
+wuffs_deflate__decoder__alloc() {
+  wuffs_deflate__decoder* x =
+      (wuffs_deflate__decoder*)(calloc(sizeof(wuffs_deflate__decoder), 1));
+  if (!x) {
+    return NULL;
+  }
+  if (wuffs_deflate__decoder__initialize(x, sizeof(wuffs_deflate__decoder),
+                                         WUFFS_VERSION,
+                                         WUFFS_INITIALIZE__ALREADY_ZEROED)
+          .repr) {
+    free(x);
+    return NULL;
+  }
+  return x;
+}
+
 size_t  //
 sizeof__wuffs_deflate__decoder() {
   return sizeof(wuffs_deflate__decoder);
@@ -15087,6 +15534,23 @@
   return wuffs_base__make_status(NULL);
 }
 
+wuffs_lzw__decoder*  //
+wuffs_lzw__decoder__alloc() {
+  wuffs_lzw__decoder* x =
+      (wuffs_lzw__decoder*)(calloc(sizeof(wuffs_lzw__decoder), 1));
+  if (!x) {
+    return NULL;
+  }
+  if (wuffs_lzw__decoder__initialize(x, sizeof(wuffs_lzw__decoder),
+                                     WUFFS_VERSION,
+                                     WUFFS_INITIALIZE__ALREADY_ZEROED)
+          .repr) {
+    free(x);
+    return NULL;
+  }
+  return x;
+}
+
 size_t  //
 sizeof__wuffs_lzw__decoder() {
   return sizeof(wuffs_lzw__decoder);
@@ -15807,6 +16271,23 @@
   return wuffs_base__make_status(NULL);
 }
 
+wuffs_gif__config_decoder*  //
+wuffs_gif__config_decoder__alloc() {
+  wuffs_gif__config_decoder* x = (wuffs_gif__config_decoder*)(calloc(
+      sizeof(wuffs_gif__config_decoder), 1));
+  if (!x) {
+    return NULL;
+  }
+  if (wuffs_gif__config_decoder__initialize(
+          x, sizeof(wuffs_gif__config_decoder), WUFFS_VERSION,
+          WUFFS_INITIALIZE__ALREADY_ZEROED)
+          .repr) {
+    free(x);
+    return NULL;
+  }
+  return x;
+}
+
 size_t  //
 sizeof__wuffs_gif__config_decoder() {
   return sizeof(wuffs_gif__config_decoder);
@@ -15868,6 +16349,23 @@
   return wuffs_base__make_status(NULL);
 }
 
+wuffs_gif__decoder*  //
+wuffs_gif__decoder__alloc() {
+  wuffs_gif__decoder* x =
+      (wuffs_gif__decoder*)(calloc(sizeof(wuffs_gif__decoder), 1));
+  if (!x) {
+    return NULL;
+  }
+  if (wuffs_gif__decoder__initialize(x, sizeof(wuffs_gif__decoder),
+                                     WUFFS_VERSION,
+                                     WUFFS_INITIALIZE__ALREADY_ZEROED)
+          .repr) {
+    free(x);
+    return NULL;
+  }
+  return x;
+}
+
 size_t  //
 sizeof__wuffs_gif__decoder() {
   return sizeof(wuffs_gif__decoder);
@@ -20324,6 +20822,23 @@
   return wuffs_base__make_status(NULL);
 }
 
+wuffs_gzip__decoder*  //
+wuffs_gzip__decoder__alloc() {
+  wuffs_gzip__decoder* x =
+      (wuffs_gzip__decoder*)(calloc(sizeof(wuffs_gzip__decoder), 1));
+  if (!x) {
+    return NULL;
+  }
+  if (wuffs_gzip__decoder__initialize(x, sizeof(wuffs_gzip__decoder),
+                                      WUFFS_VERSION,
+                                      WUFFS_INITIALIZE__ALREADY_ZEROED)
+          .repr) {
+    free(x);
+    return NULL;
+  }
+  return x;
+}
+
 size_t  //
 sizeof__wuffs_gzip__decoder() {
   return sizeof(wuffs_gzip__decoder);
@@ -20958,6 +21473,23 @@
   return wuffs_base__make_status(NULL);
 }
 
+wuffs_json__decoder*  //
+wuffs_json__decoder__alloc() {
+  wuffs_json__decoder* x =
+      (wuffs_json__decoder*)(calloc(sizeof(wuffs_json__decoder), 1));
+  if (!x) {
+    return NULL;
+  }
+  if (wuffs_json__decoder__initialize(x, sizeof(wuffs_json__decoder),
+                                      WUFFS_VERSION,
+                                      WUFFS_INITIALIZE__ALREADY_ZEROED)
+          .repr) {
+    free(x);
+    return NULL;
+  }
+  return x;
+}
+
 size_t  //
 sizeof__wuffs_json__decoder() {
   return sizeof(wuffs_json__decoder);
@@ -23131,6 +23663,23 @@
   return wuffs_base__make_status(NULL);
 }
 
+wuffs_wbmp__decoder*  //
+wuffs_wbmp__decoder__alloc() {
+  wuffs_wbmp__decoder* x =
+      (wuffs_wbmp__decoder*)(calloc(sizeof(wuffs_wbmp__decoder), 1));
+  if (!x) {
+    return NULL;
+  }
+  if (wuffs_wbmp__decoder__initialize(x, sizeof(wuffs_wbmp__decoder),
+                                      WUFFS_VERSION,
+                                      WUFFS_INITIALIZE__ALREADY_ZEROED)
+          .repr) {
+    free(x);
+    return NULL;
+  }
+  return x;
+}
+
 size_t  //
 sizeof__wuffs_wbmp__decoder() {
   return sizeof(wuffs_wbmp__decoder);
@@ -23926,6 +24475,23 @@
   return wuffs_base__make_status(NULL);
 }
 
+wuffs_zlib__decoder*  //
+wuffs_zlib__decoder__alloc() {
+  wuffs_zlib__decoder* x =
+      (wuffs_zlib__decoder*)(calloc(sizeof(wuffs_zlib__decoder), 1));
+  if (!x) {
+    return NULL;
+  }
+  if (wuffs_zlib__decoder__initialize(x, sizeof(wuffs_zlib__decoder),
+                                      WUFFS_VERSION,
+                                      WUFFS_INITIALIZE__ALREADY_ZEROED)
+          .repr) {
+    free(x);
+    return NULL;
+  }
+  return x;
+}
+
 size_t  //
 sizeof__wuffs_zlib__decoder() {
   return sizeof(wuffs_zlib__decoder);