diff --git a/Setup.hs b/Setup.hs
--- a/Setup.hs
+++ b/Setup.hs
@@ -1,6 +1,6 @@
 -- This file is part of Hoppy.
 --
--- Copyright 2015-2018 Bryan Gardiner <bog@khumba.net>
+-- Copyright 2015-2019 Bryan Gardiner <bog@khumba.net>
 --
 -- Licensed under the Apache License, Version 2.0 (the "License");
 -- you may not use this file except in compliance with the License.
diff --git a/hoppy-std.cabal b/hoppy-std.cabal
--- a/hoppy-std.cabal
+++ b/hoppy-std.cabal
@@ -1,12 +1,12 @@
 name: hoppy-std
-version: 0.5.0
+version: 0.6.0
 synopsis: C++ FFI generator - Standard library bindings
 homepage: http://khumba.net/projects/hoppy
 license: Apache-2.0
 license-file: LICENSE
 author: Bryan Gardiner <bog@khumba.net>
 maintainer: Bryan Gardiner <bog@khumba.net>
-copyright: Copyright 2015-2018 Bryan Gardiner
+copyright: Copyright 2015-2019 Bryan Gardiner
 category: Foreign
 build-type: Simple
 cabal-version: >=1.10
@@ -35,6 +35,7 @@
     , Foreign.Hoppy.Generator.Std.UnorderedMap
     , Foreign.Hoppy.Generator.Std.UnorderedSet
     , Foreign.Hoppy.Generator.Std.Vector
+    , Foreign.Hoppy.Generator.Std.Wstring
   other-modules:
       Foreign.Hoppy.Generator.Std.Internal
     , Paths_hoppy_std
@@ -42,7 +43,7 @@
       base >=4.7 && <5
     , filepath >=1.0 && <1.5
     , haskell-src >=1.0 && <1.1
-    , hoppy-generator >=0.5 && <0.6
+    , hoppy-generator >=0.6 && <0.7
   hs-source-dirs: src
   ghc-options: -W -fwarn-incomplete-patterns -fwarn-unused-do-bind
   default-language: Haskell2010
diff --git a/include/hoppy/std/iterator.hpp b/include/hoppy/std/iterator.hpp
--- a/include/hoppy/std/iterator.hpp
+++ b/include/hoppy/std/iterator.hpp
@@ -3,7 +3,7 @@
 
 // This file is part of Hoppy.
 //
-// Copyright 2015-2018 Bryan Gardiner <bog@khumba.net>
+// Copyright 2015-2019 Bryan Gardiner <bog@khumba.net>
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
diff --git a/include/hoppy/std/map.hpp b/include/hoppy/std/map.hpp
--- a/include/hoppy/std/map.hpp
+++ b/include/hoppy/std/map.hpp
@@ -3,7 +3,7 @@
 
 // This file is part of Hoppy.
 //
-// Copyright 2015-2018 Bryan Gardiner <bog@khumba.net>
+// Copyright 2015-2019 Bryan Gardiner <bog@khumba.net>
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
diff --git a/include/hoppy/std/set.hpp b/include/hoppy/std/set.hpp
--- a/include/hoppy/std/set.hpp
+++ b/include/hoppy/std/set.hpp
@@ -3,7 +3,7 @@
 
 // This file is part of Hoppy.
 //
-// Copyright 2015-2018 Bryan Gardiner <bog@khumba.net>
+// Copyright 2015-2019 Bryan Gardiner <bog@khumba.net>
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
diff --git a/include/hoppy/std/unordered_map.hpp b/include/hoppy/std/unordered_map.hpp
--- a/include/hoppy/std/unordered_map.hpp
+++ b/include/hoppy/std/unordered_map.hpp
@@ -3,7 +3,7 @@
 
 // This file is part of Hoppy.
 //
-// Copyright 2015-2018 Bryan Gardiner <bog@khumba.net>
+// Copyright 2015-2019 Bryan Gardiner <bog@khumba.net>
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
diff --git a/include/hoppy/std/unordered_set.hpp b/include/hoppy/std/unordered_set.hpp
--- a/include/hoppy/std/unordered_set.hpp
+++ b/include/hoppy/std/unordered_set.hpp
@@ -3,7 +3,7 @@
 
 // This file is part of Hoppy.
 //
-// Copyright 2015-2018 Bryan Gardiner <bog@khumba.net>
+// Copyright 2015-2019 Bryan Gardiner <bog@khumba.net>
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
diff --git a/include/hoppy/std/utility.hpp b/include/hoppy/std/utility.hpp
--- a/include/hoppy/std/utility.hpp
+++ b/include/hoppy/std/utility.hpp
@@ -3,7 +3,7 @@
 
 // This file is part of Hoppy.
 //
-// Copyright 2015-2018 Bryan Gardiner <bog@khumba.net>
+// Copyright 2015-2019 Bryan Gardiner <bog@khumba.net>
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
diff --git a/src/Foreign/Hoppy/Generator/Std.hs b/src/Foreign/Hoppy/Generator/Std.hs
--- a/src/Foreign/Hoppy/Generator/Std.hs
+++ b/src/Foreign/Hoppy/Generator/Std.hs
@@ -1,6 +1,6 @@
 -- This file is part of Hoppy.
 --
--- Copyright 2015-2018 Bryan Gardiner <bog@khumba.net>
+-- Copyright 2015-2019 Bryan Gardiner <bog@khumba.net>
 --
 -- Licensed under the Apache License, Version 2.0 (the "License");
 -- you may not use this file except in compliance with the License.
@@ -23,6 +23,7 @@
 
 import Foreign.Hoppy.Generator.Spec
 import Foreign.Hoppy.Generator.Std.String (c_string)
+import Foreign.Hoppy.Generator.Std.Wstring (c_wstring)
 
 {-# ANN module "HLint: ignore Use camelCase" #-}
 
@@ -42,4 +43,6 @@
 mod_std :: Module
 mod_std = moduleModify' (makeModule "std" "std.hpp" "std.cpp") $
   moduleAddExports
-  [ ExportClass c_string ]
+  [ Export c_string
+  , Export c_wstring
+  ]
diff --git a/src/Foreign/Hoppy/Generator/Std/Internal.hs b/src/Foreign/Hoppy/Generator/Std/Internal.hs
--- a/src/Foreign/Hoppy/Generator/Std/Internal.hs
+++ b/src/Foreign/Hoppy/Generator/Std/Internal.hs
@@ -1,6 +1,6 @@
 -- This file is part of Hoppy.
 --
--- Copyright 2015-2018 Bryan Gardiner <bog@khumba.net>
+-- Copyright 2015-2019 Bryan Gardiner <bog@khumba.net>
 --
 -- Licensed under the Apache License, Version 2.0 (the "License");
 -- you may not use this file except in compliance with the License.
diff --git a/src/Foreign/Hoppy/Generator/Std/Iterator.hs b/src/Foreign/Hoppy/Generator/Std/Iterator.hs
--- a/src/Foreign/Hoppy/Generator/Std/Iterator.hs
+++ b/src/Foreign/Hoppy/Generator/Std/Iterator.hs
@@ -1,6 +1,6 @@
 -- This file is part of Hoppy.
 --
--- Copyright 2015-2018 Bryan Gardiner <bog@khumba.net>
+-- Copyright 2015-2019 Bryan Gardiner <bog@khumba.net>
 --
 -- Licensed under the Apache License, Version 2.0 (the "License");
 -- you may not use this file except in compliance with the License.
@@ -28,9 +28,7 @@
 
 import Data.Maybe (catMaybes, isJust)
 import Foreign.Hoppy.Generator.Spec (
-  Class,
   ClassFeature (Assignable, Copyable, Equatable),
-  MethodApplicability (MNormal),
   Operator (
     OpAdd,
     OpAddAssign,
@@ -43,15 +41,20 @@
   Purity (Nonpure),
   Type,
   addReqIncludes,
-  classAddEntities,
   classAddFeatures,
   ident2,
+  np,
+  )
+import Foreign.Hoppy.Generator.Types
+import Foreign.Hoppy.Generator.Spec.Class (
+  Class,
+  MethodApplicability (MNormal),
+  classAddEntities,
   makeFnMethod,
   mkConstMethod',
   mkCtor,
   mkMethod',
   )
-import Foreign.Hoppy.Generator.Types
 import Foreign.Hoppy.Generator.Std.Internal (includeHelper)
 
 -- | Whether an iterator may be used to modify the underlying collection.
@@ -82,12 +85,12 @@
   classAddEntities ents cls
   where ents =
           catMaybes
-          [ Just $ mkCtor "new" []
+          [ Just $ mkCtor "new" np
           , do valueType <- valueTypeMaybe
                Mutable <- Just mutable
-               return $ mkMethod' OpDeref "get" [] $ refT valueType
+               return $ mkMethod' OpDeref "get" np $ refT valueType
           , do valueType <- valueTypeMaybe
-               return $ mkConstMethod' OpDeref "getConst" [] $ refT $ constT valueType
+               return $ mkConstMethod' OpDeref "getConst" np $ refT $ constT valueType
           , do valueType <- valueTypeMaybe
                Mutable <- Just mutable
                return $
@@ -104,7 +107,7 @@
   classAddEntities ents $
   makeTrivialIterator mutable valueTypeMaybe cls
   where ents =
-          [ mkMethod' OpIncPre "next" [] $ refT $ objT cls
+          [ mkMethod' OpIncPre "next" np $ refT $ objT cls
           ]
 
 -- | Turns a class into a bidirectional iterator, including everything from
@@ -116,7 +119,7 @@
   classAddEntities ents $
   makeForwardIterator mutability valueTypeMaybe cls
   where ents =
-          [ mkMethod' OpDecPre "prev" [] $ refT $ objT cls
+          [ mkMethod' OpDecPre "prev" np $ refT $ objT cls
           ]
 
 -- | @makeRandomIterator mutable valueTypeMaybe distanceType cls@ turns a class
diff --git a/src/Foreign/Hoppy/Generator/Std/List.hs b/src/Foreign/Hoppy/Generator/Std/List.hs
--- a/src/Foreign/Hoppy/Generator/Std/List.hs
+++ b/src/Foreign/Hoppy/Generator/Std/List.hs
@@ -1,6 +1,6 @@
 -- This file is part of Hoppy.
 --
--- Copyright 2015-2018 Bryan Gardiner <bog@khumba.net>
+-- Copyright 2015-2019 Bryan Gardiner <bog@khumba.net>
 --
 -- Licensed under the Apache License, Version 2.0 (the "License");
 -- you may not use this file except in compliance with the License.
@@ -39,10 +39,21 @@
   prettyPrint,
   sayLn,
   saysLn,
+  )
+import Foreign.Hoppy.Generator.Spec
+import Foreign.Hoppy.Generator.Spec.Class (
+  Class,
+  MethodApplicability (MConst),
+  makeClass,
+  makeFnMethod,
+  mkConstMethod,
+  mkConstMethod',
+  mkCtor,
+  mkMethod,
+  mkMethod',
   toHsDataTypeName,
   toHsClassEntityName,
   )
-import Foreign.Hoppy.Generator.Spec
 import Foreign.Hoppy.Generator.Std (ValueConversion (ConvertPtr, ConvertValue))
 import Foreign.Hoppy.Generator.Std.Iterator
 import Foreign.Hoppy.Generator.Types
@@ -92,34 +103,34 @@
         classAddFeatures features $
         makeClass (ident1T "std" "list" [t]) (Just $ toExtName listName) [] $
         collect
-        [ just $ mkCtor "new" []
-        , just $ mkMethod' "back" "back" [] $ refT t
-        , just $ mkConstMethod' "back" "backConst" [] $ refT $ constT t
-        , just $ mkMethod' "begin" "begin" [] $ toGcT $ objT iterator
-        , just $ mkConstMethod' "begin" "beginConst" [] $ toGcT $ objT constIterator
-        , just $ mkMethod "clear" [] voidT
-        , just $ mkConstMethod "empty" [] boolT
-        , just $ mkMethod' "end" "end" [] $ toGcT $ objT iterator
-        , just $ mkConstMethod' "end" "endConst" [] $ toGcT $ objT constIterator
+        [ just $ mkCtor "new" np
+        , just $ mkMethod' "back" "back" np $ refT t
+        , just $ mkConstMethod' "back" "backConst" np $ refT $ constT t
+        , just $ mkMethod' "begin" "begin" np $ toGcT $ objT iterator
+        , just $ mkConstMethod' "begin" "beginConst" np $ toGcT $ objT constIterator
+        , just $ mkMethod "clear" np voidT
+        , just $ mkConstMethod "empty" np boolT
+        , just $ mkMethod' "end" "end" np $ toGcT $ objT iterator
+        , just $ mkConstMethod' "end" "endConst" np $ toGcT $ objT constIterator
         , just $ mkMethod' "erase" "erase" [objT iterator] voidT
         , just $ mkMethod' "erase" "eraseRange" [objT iterator, objT iterator] voidT
-        , just $ mkMethod' "front" "front" [] $ refT t
-        , just $ mkConstMethod' "front" "frontConst" [] $ refT $ constT t
+        , just $ mkMethod' "front" "front" np $ refT t
+        , just $ mkConstMethod' "front" "frontConst" np $ refT $ constT t
         , just $ mkMethod "insert" [objT iterator, t] $ toGcT $ objT iterator
-        , just $ mkConstMethod' "max_size" "maxSize" [] sizeT
+        , just $ mkConstMethod' "max_size" "maxSize" np sizeT
         , test (elem Comparable features) $ mkMethod "merge" [refT $ objT list] voidT
           -- TODO merge(list&, Comparator)
-        , just $ mkMethod' "pop_back" "popBack" [] voidT
-        , just $ mkMethod' "pop_front" "popFront" [] voidT
+        , just $ mkMethod' "pop_back" "popBack" np voidT
+        , just $ mkMethod' "pop_front" "popFront" np voidT
         , just $ mkMethod' "push_back" "pushBack" [t] voidT
         , just $ mkMethod' "push_front" "pushFront" [t] voidT
-        , test (elem Equatable features) $ mkMethod "remove" [t] voidT
+        , test (Equatable `elem` features) $ mkMethod "remove" [t] voidT
           -- TODO remove_if(UnaryPredicate)
         , just $ mkMethod' "resize" "resize" [sizeT] voidT
         , just $ mkMethod' "resize" "resizeWith" [sizeT, t] voidT
-        , just $ mkMethod "reverse" [] voidT
-        , just $ mkConstMethod "size" [] sizeT
-        , test (elem Comparable features) $ mkMethod "sort" [] voidT
+        , just $ mkMethod "reverse" np voidT
+        , just $ mkConstMethod "size" np sizeT
+        , test (elem Comparable features) $ mkMethod "sort" np voidT
           -- TODO sort(Comparator)
         , just $ mkMethod' "splice" "spliceAll" [objT iterator, refT $ objT list] voidT
         , just $ mkMethod' "splice" "spliceOne"
@@ -127,7 +138,7 @@
         , just $ mkMethod' "splice" "spliceRange"
           [objT iterator, refT $ objT list, objT iterator, objT iterator] voidT
         , just $ mkMethod "swap" [refT $ objT list] voidT
-        , test (Equatable `elem` features) $ mkMethod "unique" [] voidT
+        , test (Equatable `elem` features) $ mkMethod "unique" np voidT
           -- TODO unique(BinaryPredicate)
         ]
 
@@ -235,4 +246,4 @@
 -- | Converts an instantiation into a list of exports to be included in a
 -- module.
 toExports :: Contents -> [Export]
-toExports m = map (ExportClass . ($ m)) [c_list, c_iterator, c_constIterator]
+toExports m = map (Export . ($ m)) [c_list, c_iterator, c_constIterator]
diff --git a/src/Foreign/Hoppy/Generator/Std/Map.hs b/src/Foreign/Hoppy/Generator/Std/Map.hs
--- a/src/Foreign/Hoppy/Generator/Std/Map.hs
+++ b/src/Foreign/Hoppy/Generator/Std/Map.hs
@@ -1,6 +1,6 @@
 -- This file is part of Hoppy.
 --
--- Copyright 2015-2018 Bryan Gardiner <bog@khumba.net>
+-- Copyright 2015-2019 Bryan Gardiner <bog@khumba.net>
 --
 -- Licensed under the Apache License, Version 2.0 (the "License");
 -- you may not use this file except in compliance with the License.
@@ -39,10 +39,21 @@
   prettyPrint,
   sayLn,
   saysLn,
+  )
+import Foreign.Hoppy.Generator.Spec
+import Foreign.Hoppy.Generator.Spec.Class (
+  Class,
+  MethodApplicability (MConst, MNormal),
+  makeClass,
+  makeFnMethod,
+  mkConstMethod,
+  mkConstMethod',
+  mkCtor,
+  mkMethod,
+  mkMethod',
   toHsDataTypeName,
   toHsClassEntityName,
   )
-import Foreign.Hoppy.Generator.Spec
 import Foreign.Hoppy.Generator.Std (ValueConversion (ConvertPtr, ConvertValue))
 import Foreign.Hoppy.Generator.Std.Internal (includeHelper)
 import Foreign.Hoppy.Generator.Std.Iterator
@@ -93,7 +104,7 @@
       getIteratorKeyIdent = ident2T "hoppy" "map" "getIteratorKey" [k, v]
       getIteratorValueIdent = ident2T "hoppy" "map" "getIteratorValue" [k, v]
 
-      map =
+      map' =
         (case (optKeyConversion opts, optValueConversion opts) of
            (Nothing, Nothing) -> id
            (Just keyConv, Just valueConv) -> addAddendumHaskell $ makeAddendum keyConv valueConv
@@ -106,16 +117,16 @@
         addReqs reqs $
         classAddFeatures (Assignable : Copyable : optMapClassFeatures opts) $
         makeClass (ident1T "std" "map" [k, v]) (Just extName) []
-        [ mkCtor "new" []
+        [ mkCtor "new" np
         , mkMethod' "at" "at" [k] $ refT v
         , mkConstMethod' "at" "atConst" [k] $ refT $ constT v
-        , mkMethod' "begin" "begin" [] $ toGcT $ objT iterator
-        , mkConstMethod' "begin" "beginConst" [] $ toGcT $ objT constIterator
-        , mkMethod "clear" [] voidT
+        , mkMethod' "begin" "begin" np $ toGcT $ objT iterator
+        , mkConstMethod' "begin" "beginConst" np $ toGcT $ objT constIterator
+        , mkMethod "clear" np voidT
         , mkConstMethod "count" [k] sizeT
-        , mkConstMethod "empty" [] boolT
-        , mkMethod' "end" "end" [] $ toGcT $ objT iterator
-        , mkConstMethod' "end" "endConst" [] $ toGcT $ objT constIterator
+        , mkConstMethod "empty" np boolT
+        , mkMethod' "end" "end" np $ toGcT $ objT iterator
+        , mkConstMethod' "end" "endConst" np $ toGcT $ objT constIterator
           -- equal_range: find is good enough.
         , mkMethod' "erase" "erase" [objT iterator] voidT
         , mkMethod' "erase" "eraseKey" [k] sizeT
@@ -124,9 +135,9 @@
         , mkConstMethod' "find" "findConst" [k] $ toGcT $ objT constIterator
           -- TODO insert
           -- lower_bound: find is good enough.
-        , mkConstMethod' "max_size" "maxSize" [] sizeT
-        , mkConstMethod "size" [] sizeT
-        , mkMethod "swap" [refT $ objT map] voidT
+        , mkConstMethod' "max_size" "maxSize" np sizeT
+        , mkConstMethod "size" np sizeT
+        , mkMethod "swap" [refT $ objT map'] voidT
           -- upper_bound: find is good enough.
         , mkMethod OpArray [k] $ refT v
         ]
@@ -156,7 +167,7 @@
         []
         [ mkCtor "newFromConst" [objT iterator]
         , makeFnMethod (ident2 "hoppy" "iterator" "deconst") "deconst" MConst Nonpure
-          [objT constIterator, refT $ objT map] $ toGcT $ objT iterator
+          [objT constIterator, refT $ objT map'] $ toGcT $ objT iterator
         , makeFnMethod getIteratorKeyIdent "getKey" MConst Nonpure
           [objT constIterator] $ refT $ constT k
         , makeFnMethod getIteratorValueIdent "getValueConst" MConst Nonpure
@@ -171,7 +182,7 @@
                               hsImportForRuntime]
 
         forM_ [Const, Nonconst] $ \cst -> do
-          hsDataTypeName <- toHsDataTypeName cst map
+          hsDataTypeName <- toHsDataTypeName cst map'
 
           keyHsType <-
             cppTypeToHsTypeAndUse HsHsSide $
@@ -196,11 +207,11 @@
           indent $ do
             sayLn "toContents this' = do"
             indent $ do
-              mapEmpty <- toHsClassEntityName map "empty"
-              mapBegin <- toHsClassEntityName map $ case cst of
+              mapEmpty <- toHsClassEntityName map' "empty"
+              mapBegin <- toHsClassEntityName map' $ case cst of
                 Const -> "beginConst"
                 Nonconst -> "begin"
-              mapEnd <- toHsClassEntityName map $ case cst of
+              mapEnd <- toHsClassEntityName map' $ case cst of
                 Const -> "endConst"
                 Nonconst -> "end"
               let iter = case cst of
@@ -247,15 +258,15 @@
             indent $ do
               sayLn "fromContents values' = do"
               indent $ do
-                mapNew <- toHsClassEntityName map "new"
-                mapAt <- toHsClassEntityName map "at"
+                mapNew <- toHsClassEntityName map' "new"
+                mapAt <- toHsClassEntityName map' "at"
                 saysLn ["map' <- ", mapNew]
                 saysLn ["HoppyP.mapM_ (\\(k, v) -> HoppyP.flip HoppyFHR.assign v =<< ",
                         mapAt, " map' k) values'"]
                 sayLn "HoppyP.return map'"
 
   in Contents
-     { c_map = map
+     { c_map = map'
      , c_iterator = iterator
      , c_constIterator = constIterator
      }
@@ -263,4 +274,4 @@
 -- | Converts an instantiation into a list of exports to be included in a
 -- module.
 toExports :: Contents -> [Export]
-toExports m = map (ExportClass . ($ m)) [c_map, c_iterator, c_constIterator]
+toExports m = map (Export . ($ m)) [c_map, c_iterator, c_constIterator]
diff --git a/src/Foreign/Hoppy/Generator/Std/Pair.hs b/src/Foreign/Hoppy/Generator/Std/Pair.hs
--- a/src/Foreign/Hoppy/Generator/Std/Pair.hs
+++ b/src/Foreign/Hoppy/Generator/Std/Pair.hs
@@ -1,6 +1,6 @@
 -- This file is part of Hoppy.
 --
--- Copyright 2015-2018 Bryan Gardiner <bog@khumba.net>
+-- Copyright 2015-2019 Bryan Gardiner <bog@khumba.net>
 --
 -- Licensed under the Apache License, Version 2.0 (the "License");
 -- you may not use this file except in compliance with the License.
@@ -30,12 +30,20 @@
 import Data.Monoid (mconcat)
 #endif
 import Foreign.Hoppy.Generator.Spec
+import Foreign.Hoppy.Generator.Spec.Class (
+  Class,
+  MethodApplicability (MConst, MNormal),
+  makeClass,
+  makeFnMethod,
+  mkCtor,
+  mkMethod,
+  )
 import Foreign.Hoppy.Generator.Std.Internal (includeHelper)
 import Foreign.Hoppy.Generator.Types
 import Foreign.Hoppy.Generator.Version (CppVersion (Cpp2011), activeCppVersion, collect, just, test)
 
 -- | Options for instantiating @pair@.
-data Options = Options
+newtype Options = Options
   { optPairClassFeatures :: [ClassFeature]
     -- ^ Additional features to add to the @std::pair@ class.  Pairs are always
     -- 'Assignable' and 'Copyable'.
@@ -46,7 +54,7 @@
 defaultOptions = Options []
 
 -- | A set of instantiated pair classes.
-data Contents = Contents
+newtype Contents = Contents
   { c_pair :: Class  -- ^ @std::pair\<A, B>@
   }
 
@@ -70,7 +78,7 @@
         classAddFeatures (Assignable : Copyable : optPairClassFeatures opts) $
         makeClass (ident1T "std" "pair" [a, b]) (Just $ toExtName pairName) [] $
         collect
-        [ just $ mkCtor "new" []
+        [ just $ mkCtor "new" np
         , just $ mkCtor "newWith" [a, b]
         , just $ makeFnMethod (ident2 "hoppy" "utility" "pairFirst") "first" MNormal Nonpure
           [refT $ objT pair] $ refT a
@@ -90,4 +98,4 @@
 -- | Converts an instantiation into a list of exports to be included in a
 -- module.
 toExports :: Contents -> [Export]
-toExports m = map (ExportClass . ($ m)) [c_pair]
+toExports m = map (Export . ($ m)) [c_pair]
diff --git a/src/Foreign/Hoppy/Generator/Std/Set.hs b/src/Foreign/Hoppy/Generator/Std/Set.hs
--- a/src/Foreign/Hoppy/Generator/Std/Set.hs
+++ b/src/Foreign/Hoppy/Generator/Std/Set.hs
@@ -1,6 +1,6 @@
 -- This file is part of Hoppy.
 --
--- Copyright 2015-2018 Bryan Gardiner <bog@khumba.net>
+-- Copyright 2015-2019 Bryan Gardiner <bog@khumba.net>
 --
 -- Licensed under the Apache License, Version 2.0 (the "License");
 -- you may not use this file except in compliance with the License.
@@ -26,7 +26,7 @@
   toExports,
   ) where
 
-import Control.Monad (forM, when)
+import Control.Monad (when)
 #if !MIN_VERSION_base(4,8,0)
 import Data.Monoid (mconcat)
 #endif
@@ -39,11 +39,22 @@
   prettyPrint,
   sayLn,
   saysLn,
+  )
+import Foreign.Hoppy.Generator.Spec
+import Foreign.Hoppy.Generator.Spec.Class (
+  Class,
+  MethodApplicability (MNormal),
+  makeClass,
+  makeFnMethod,
+  mkConstMethod,
+  mkConstMethod',
+  mkCtor,
+  mkMethod,
+  mkMethod',
   toHsCastMethodName,
   toHsDataTypeName,
   toHsClassEntityName,
   )
-import Foreign.Hoppy.Generator.Spec
 import Foreign.Hoppy.Generator.Std (ValueConversion (ConvertPtr, ConvertValue))
 import Foreign.Hoppy.Generator.Std.Internal (includeHelper)
 import Foreign.Hoppy.Generator.Std.Iterator
@@ -94,15 +105,15 @@
         addReqs reqs $
         classAddFeatures (Assignable : Comparable : Copyable : optSetClassFeatures opts) $
         makeClass (ident1T "std" "set" [t]) (Just $ toExtName setName) []
-        [ mkCtor "new" []
-        , mkMethod' "begin" "begin" [] $ toGcT $ objT iterator
-        , mkConstMethod' "begin" "beginConst" [] $ toGcT $ objT constIterator
-        , mkMethod "clear" [] voidT
+        [ mkCtor "new" np
+        , mkMethod' "begin" "begin" np $ toGcT $ objT iterator
+        , mkConstMethod' "begin" "beginConst" np $ toGcT $ objT constIterator
+        , mkMethod "clear" np voidT
         , mkConstMethod "count" [t] sizeT
           -- TODO count
-        , mkConstMethod "empty" [] boolT
-        , mkMethod' "end" "end" [] $ toGcT $ objT iterator
-        , mkConstMethod' "end" "endConst" [] $ toGcT $ objT constIterator
+        , mkConstMethod "empty" np boolT
+        , mkMethod' "end" "end" np $ toGcT $ objT iterator
+        , mkConstMethod' "end" "endConst" np $ toGcT $ objT constIterator
           -- equalRange: find is good enough.
         , mkMethod' "erase" "erase" [objT iterator] voidT
         , mkMethod' "erase" "eraseRange" [objT iterator, objT iterator] voidT
@@ -113,8 +124,8 @@
         , makeFnMethod (ident2 "hoppy" "set" "insertAndGetIterator") "insertAndGetIterator"
           MNormal Nonpure [refT $ objT set, t] $ toGcT $ objT iterator
           -- lower_bound: find is good enough.
-        , mkConstMethod' "max_size" "maxSize" [] sizeT
-        , mkConstMethod "size" [] sizeT
+        , mkConstMethod' "max_size" "maxSize" np sizeT
+        , mkConstMethod "size" np sizeT
         , mkMethod "swap" [refT $ objT set] voidT
           -- upper_bound: find is good enough.
         ]
@@ -146,15 +157,18 @@
 
         hsDataNameConst <- toHsDataTypeName Const set
         hsDataName <- toHsDataTypeName Nonconst set
-        [hsValueTypeConst, hsValueType] <- forM [Const, Nonconst] $ \cst ->
-            cppTypeToHsTypeAndUse HsHsSide $
-            (case conversion of
-               ConvertPtr -> ptrT
-               ConvertValue -> id) $
-            case cst of
-              Const -> constT t
-              Nonconst -> t
 
+        let computeValueType cst =
+              cppTypeToHsTypeAndUse HsHsSide $
+              (case conversion of
+                 ConvertPtr -> ptrT
+                 ConvertValue -> id) $
+              case cst of
+                Const -> constT t
+                Nonconst -> t
+        hsValueTypeConst <- computeValueType Const
+        hsValueType <- computeValueType Nonconst
+
         setConstCast <- toHsCastMethodName Const set
         setEmpty <- toHsClassEntityName set "empty"
         setBeginConst <- toHsClassEntityName set "beginConst"
@@ -218,4 +232,4 @@
 -- | Converts an instantiation into a list of exports to be included in a
 -- module.
 toExports :: Contents -> [Export]
-toExports m = map (ExportClass . ($ m)) [c_set, c_iterator, c_constIterator]
+toExports m = map (Export . ($ m)) [c_set, c_iterator, c_constIterator]
diff --git a/src/Foreign/Hoppy/Generator/Std/String.hs b/src/Foreign/Hoppy/Generator/Std/String.hs
--- a/src/Foreign/Hoppy/Generator/Std/String.hs
+++ b/src/Foreign/Hoppy/Generator/Std/String.hs
@@ -1,6 +1,6 @@
 -- This file is part of Hoppy.
 --
--- Copyright 2015-2018 Bryan Gardiner <bog@khumba.net>
+-- Copyright 2015-2019 Bryan Gardiner <bog@khumba.net>
 --
 -- Licensed under the Apache License, Version 2.0 (the "License");
 -- you may not use this file except in compliance with the License.
@@ -24,6 +24,16 @@
 #endif
 import Foreign.Hoppy.Generator.Language.Haskell (addExport, addImports, indent, sayLn)
 import Foreign.Hoppy.Generator.Spec
+import Foreign.Hoppy.Generator.Spec.Class (
+  Class,
+  ClassHaskellConversion (..),
+  classSetHaskellConversion,
+  makeClass,
+  mkCtor,
+  mkConstMethod,
+  mkConstMethod',
+  mkMethod',
+  )
 import Foreign.Hoppy.Generator.Types
 import Language.Haskell.Syntax (
   HsName (HsIdent),
@@ -57,14 +67,14 @@
           sayLn "HoppyFC.peekCStringLen (p, HoppyP.fromIntegral n) <* HoppyFHR.touchCppPtr s"
       } $
   makeClass (ident1 "std" "string") (Just $ toExtName "StdString") []
-  [ mkCtor "new" []
+  [ mkCtor "new" np
   , mkCtor "newFromCString" [ptrT $ constT charT]
   , mkCtor "newFromCStringLen_raw" [ptrT $ constT charT, sizeT]
   , mkMethod' "at" "at" [intT] $ refT charT
   , mkConstMethod' "at" "get" [intT] charT
-  , mkConstMethod "c_str" [] $ ptrT $ constT charT
-  , mkConstMethod "data" [] $ ptrT $ constT charT
-  , mkConstMethod "size" [] sizeT
+  , mkConstMethod "c_str" np $ ptrT $ constT charT
+  , mkConstMethod "data" np $ ptrT $ constT charT
+  , mkConstMethod "size" np sizeT
   ]
   where
     addendum = do
@@ -72,5 +82,4 @@
       addExport "stdString_newFromCStringLen"
       sayLn "stdString_newFromCStringLen :: HoppyFC.CStringLen -> HoppyP.IO StdString"
       sayLn "stdString_newFromCStringLen (p,n) ="
-      indent $ do
-        sayLn "stdString_newFromCStringLen_raw p (HoppyP.fromIntegral n)"
+      indent $ sayLn "stdString_newFromCStringLen_raw p (HoppyP.fromIntegral n)"
diff --git a/src/Foreign/Hoppy/Generator/Std/UnorderedMap.hs b/src/Foreign/Hoppy/Generator/Std/UnorderedMap.hs
--- a/src/Foreign/Hoppy/Generator/Std/UnorderedMap.hs
+++ b/src/Foreign/Hoppy/Generator/Std/UnorderedMap.hs
@@ -1,6 +1,6 @@
 -- This file is part of Hoppy.
 --
--- Copyright 2015-2018 Bryan Gardiner <bog@khumba.net>
+-- Copyright 2015-2019 Bryan Gardiner <bog@khumba.net>
 --
 -- Licensed under the Apache License, Version 2.0 (the "License");
 -- you may not use this file except in compliance with the License.
@@ -39,10 +39,21 @@
   prettyPrint,
   sayLn,
   saysLn,
+  )
+import Foreign.Hoppy.Generator.Spec
+import Foreign.Hoppy.Generator.Spec.Class (
+  Class,
+  MethodApplicability (MConst, MNormal),
+  makeClass,
+  makeFnMethod,
+  mkConstMethod,
+  mkConstMethod',
+  mkCtor,
+  mkMethod,
+  mkMethod',
   toHsDataTypeName,
   toHsClassEntityName,
   )
-import Foreign.Hoppy.Generator.Spec
 import Foreign.Hoppy.Generator.Std (ValueConversion (ConvertPtr, ConvertValue))
 import Foreign.Hoppy.Generator.Std.Internal (includeHelper)
 import Foreign.Hoppy.Generator.Std.Iterator
@@ -93,7 +104,7 @@
       getIteratorKeyIdent = ident2T "hoppy" "unordered_map" "getIteratorKey" [k, v]
       getIteratorValueIdent = ident2T "hoppy" "unordered_map" "getIteratorValue" [k, v]
 
-      map =
+      map' =
         (case (optKeyConversion opts, optValueConversion opts) of
            (Nothing, Nothing) -> id
            (Just keyConv, Just valueConv) -> addAddendumHaskell $ makeAddendum keyConv valueConv
@@ -106,16 +117,16 @@
         addReqs reqs $
         classAddFeatures (Assignable : Copyable : optUnorderedMapClassFeatures opts) $
         makeClass (ident1T "std" "unordered_map" [k, v]) (Just extName) []
-        [ mkCtor "new" []
+        [ mkCtor "new" np
         , mkMethod' "at" "at" [k] $ refT v
         , mkConstMethod' "at" "atConst" [k] $ refT $ constT v
-        , mkMethod' "begin" "begin" [] $ toGcT $ objT iterator
-        , mkConstMethod' "begin" "beginConst" [] $ toGcT $ objT constIterator
-        , mkMethod "clear" [] voidT
+        , mkMethod' "begin" "begin" np $ toGcT $ objT iterator
+        , mkConstMethod' "begin" "beginConst" np $ toGcT $ objT constIterator
+        , mkMethod "clear" np voidT
         , mkConstMethod "count" [k] sizeT
-        , mkConstMethod "empty" [] boolT
-        , mkMethod' "end" "end" [] $ toGcT $ objT iterator
-        , mkConstMethod' "end" "endConst" [] $ toGcT $ objT constIterator
+        , mkConstMethod "empty" np boolT
+        , mkMethod' "end" "end" np $ toGcT $ objT iterator
+        , mkConstMethod' "end" "endConst" np $ toGcT $ objT constIterator
           -- equal_range: find is good enough.
         , mkMethod' "erase" "erase" [objT iterator] voidT
         , mkMethod' "erase" "eraseKey" [k] sizeT
@@ -124,9 +135,9 @@
         , mkConstMethod' "find" "findConst" [k] $ toGcT $ objT constIterator
           -- TODO insert
           -- lower_bound: find is good enough.
-        , mkConstMethod' "max_size" "maxSize" [] sizeT
-        , mkConstMethod "size" [] sizeT
-        , mkMethod "swap" [refT $ objT map] voidT
+        , mkConstMethod' "max_size" "maxSize" np sizeT
+        , mkConstMethod "size" np sizeT
+        , mkMethod "swap" [refT $ objT map'] voidT
           -- upper_bound: find is good enough.
         , mkMethod OpArray [k] $ refT v
         ]
@@ -156,7 +167,7 @@
         []
         [ mkCtor "newFromConst" [objT iterator]
         , makeFnMethod (ident2 "hoppy" "iterator" "deconst") "deconst" MConst Nonpure
-          [objT constIterator, refT $ objT map] $ toGcT $ objT iterator
+          [objT constIterator, refT $ objT map'] $ toGcT $ objT iterator
         , makeFnMethod getIteratorKeyIdent "getKey" MConst Nonpure
           [objT constIterator] $ refT $ constT k
         , makeFnMethod getIteratorValueIdent "getValueConst" MConst Nonpure
@@ -171,7 +182,7 @@
                               hsImportForRuntime]
 
         forM_ [Const, Nonconst] $ \cst -> do
-          hsDataTypeName <- toHsDataTypeName cst map
+          hsDataTypeName <- toHsDataTypeName cst map'
 
           keyHsType <-
             cppTypeToHsTypeAndUse HsHsSide $
@@ -196,11 +207,11 @@
           indent $ do
             sayLn "toContents this' = do"
             indent $ do
-              mapEmpty <- toHsClassEntityName map "empty"
-              mapBegin <- toHsClassEntityName map $ case cst of
+              mapEmpty <- toHsClassEntityName map' "empty"
+              mapBegin <- toHsClassEntityName map' $ case cst of
                 Const -> "beginConst"
                 Nonconst -> "begin"
-              mapEnd <- toHsClassEntityName map $ case cst of
+              mapEnd <- toHsClassEntityName map' $ case cst of
                 Const -> "endConst"
                 Nonconst -> "end"
               let iter = case cst of
@@ -247,15 +258,15 @@
             indent $ do
               sayLn "fromContents values' = do"
               indent $ do
-                mapNew <- toHsClassEntityName map "new"
-                mapAt <- toHsClassEntityName map "at"
+                mapNew <- toHsClassEntityName map' "new"
+                mapAt <- toHsClassEntityName map' "at"
                 saysLn ["map' <- ", mapNew]
                 saysLn ["HoppyP.mapM_ (\\(k, v) -> HoppyP.flip HoppyFHR.assign v =<< ",
                         mapAt, " map' k) values'"]
                 sayLn "HoppyP.return map'"
 
   in Contents
-     { c_map = map
+     { c_map = map'
      , c_iterator = iterator
      , c_constIterator = constIterator
      }
@@ -263,4 +274,4 @@
 -- | Converts an instantiation into a list of exports to be included in a
 -- module.
 toExports :: Contents -> [Export]
-toExports m = map (ExportClass . ($ m)) [c_map, c_iterator, c_constIterator]
+toExports m = map (Export . ($ m)) [c_map, c_iterator, c_constIterator]
diff --git a/src/Foreign/Hoppy/Generator/Std/UnorderedSet.hs b/src/Foreign/Hoppy/Generator/Std/UnorderedSet.hs
--- a/src/Foreign/Hoppy/Generator/Std/UnorderedSet.hs
+++ b/src/Foreign/Hoppy/Generator/Std/UnorderedSet.hs
@@ -1,6 +1,6 @@
 -- This file is part of Hoppy.
 --
--- Copyright 2015-2018 Bryan Gardiner <bog@khumba.net>
+-- Copyright 2015-2019 Bryan Gardiner <bog@khumba.net>
 --
 -- Licensed under the Apache License, Version 2.0 (the "License");
 -- you may not use this file except in compliance with the License.
@@ -26,7 +26,7 @@
   toExports,
   ) where
 
-import Control.Monad (forM, when)
+import Control.Monad (when)
 #if !MIN_VERSION_base(4,8,0)
 import Data.Monoid (mconcat)
 #endif
@@ -39,11 +39,22 @@
   prettyPrint,
   sayLn,
   saysLn,
+  )
+import Foreign.Hoppy.Generator.Spec
+import Foreign.Hoppy.Generator.Spec.Class (
+  Class,
+  MethodApplicability (MNormal),
+  makeClass,
+  makeFnMethod,
+  mkConstMethod,
+  mkConstMethod',
+  mkCtor,
+  mkMethod,
+  mkMethod',
   toHsCastMethodName,
   toHsDataTypeName,
   toHsClassEntityName,
   )
-import Foreign.Hoppy.Generator.Spec
 import Foreign.Hoppy.Generator.Std (ValueConversion (ConvertPtr, ConvertValue))
 import Foreign.Hoppy.Generator.Std.Internal (includeHelper)
 import Foreign.Hoppy.Generator.Std.Iterator
@@ -94,15 +105,15 @@
         addReqs reqs $
         classAddFeatures (Assignable : Copyable : optUnorderedSetClassFeatures opts) $
         makeClass (ident1T "std" "unordered_set" [t]) (Just $ toExtName setName) []
-        [ mkCtor "new" []
-        , mkMethod' "begin" "begin" [] $ toGcT $ objT iterator
-        , mkConstMethod' "begin" "beginConst" [] $ toGcT $ objT constIterator
-        , mkMethod "clear" [] voidT
+        [ mkCtor "new" np
+        , mkMethod' "begin" "begin" np $ toGcT $ objT iterator
+        , mkConstMethod' "begin" "beginConst" np $ toGcT $ objT constIterator
+        , mkMethod "clear" np voidT
         , mkConstMethod "count" [t] sizeT
           -- TODO count
-        , mkConstMethod "empty" [] boolT
-        , mkMethod' "end" "end" [] $ toGcT $ objT iterator
-        , mkConstMethod' "end" "endConst" [] $ toGcT $ objT constIterator
+        , mkConstMethod "empty" np boolT
+        , mkMethod' "end" "end" np $ toGcT $ objT iterator
+        , mkConstMethod' "end" "endConst" np $ toGcT $ objT constIterator
           -- equalRange: find is good enough.
         , mkMethod' "erase" "erase" [objT iterator] voidT
         , mkMethod' "erase" "eraseRange" [objT iterator, objT iterator] voidT
@@ -113,8 +124,8 @@
         , makeFnMethod (ident2 "hoppy" "unordered_set" "insertAndGetIterator")
           "insertAndGetIterator" MNormal Nonpure [refT $ objT set, t] $ toGcT $ objT iterator
           -- lower_bound: find is good enough.
-        , mkConstMethod' "max_size" "maxSize" [] sizeT
-        , mkConstMethod "size" [] sizeT
+        , mkConstMethod' "max_size" "maxSize" np sizeT
+        , mkConstMethod "size" np sizeT
         , mkMethod "swap" [refT $ objT set] voidT
           -- upper_bound: find is good enough.
         ]
@@ -149,15 +160,18 @@
 
         hsDataNameConst <- toHsDataTypeName Const set
         hsDataName <- toHsDataTypeName Nonconst set
-        [hsValueTypeConst, hsValueType] <- forM [Const, Nonconst] $ \cst ->
-            cppTypeToHsTypeAndUse HsHsSide $
-            (case conversion of
-               ConvertPtr -> ptrT
-               ConvertValue -> id) $
-            case cst of
-              Const -> constT t
-              Nonconst -> t
 
+        let computeValueType cst =
+              cppTypeToHsTypeAndUse HsHsSide $
+              (case conversion of
+                 ConvertPtr -> ptrT
+                 ConvertValue -> id) $
+              case cst of
+                Const -> constT t
+                Nonconst -> t
+        hsValueTypeConst <- computeValueType Const
+        hsValueType <- computeValueType Nonconst
+
         setConstCast <- toHsCastMethodName Const set
         setEmpty <- toHsClassEntityName set "empty"
         setBeginConst <- toHsClassEntityName set "beginConst"
@@ -221,4 +235,4 @@
 -- | Converts an instantiation into a list of exports to be included in a
 -- module.
 toExports :: Contents -> [Export]
-toExports m = map (ExportClass . ($ m)) [c_set, c_iterator, c_constIterator]
+toExports m = map (Export . ($ m)) [c_set, c_iterator, c_constIterator]
diff --git a/src/Foreign/Hoppy/Generator/Std/Vector.hs b/src/Foreign/Hoppy/Generator/Std/Vector.hs
--- a/src/Foreign/Hoppy/Generator/Std/Vector.hs
+++ b/src/Foreign/Hoppy/Generator/Std/Vector.hs
@@ -1,6 +1,6 @@
 -- This file is part of Hoppy.
 --
--- Copyright 2015-2018 Bryan Gardiner <bog@khumba.net>
+-- Copyright 2015-2019 Bryan Gardiner <bog@khumba.net>
 --
 -- Licensed under the Apache License, Version 2.0 (the "License");
 -- you may not use this file except in compliance with the License.
@@ -39,10 +39,21 @@
   prettyPrint,
   sayLn,
   saysLn,
+  )
+import Foreign.Hoppy.Generator.Spec
+import Foreign.Hoppy.Generator.Spec.Class (
+  Class,
+  MethodApplicability (MConst),
+  makeClass,
+  makeFnMethod,
+  mkConstMethod,
+  mkConstMethod',
+  mkCtor,
+  mkMethod,
+  mkMethod',
   toHsDataTypeName,
   toHsClassEntityName,
   )
-import Foreign.Hoppy.Generator.Spec
 import Foreign.Hoppy.Generator.Std (ValueConversion (ConvertPtr, ConvertValue))
 import Foreign.Hoppy.Generator.Std.Iterator
 import Foreign.Hoppy.Generator.Types
@@ -93,31 +104,31 @@
         classAddFeatures (Assignable : Copyable : optVectorClassFeatures opts) $
         makeClass (ident1T "std" "vector" [t]) (Just $ toExtName vectorName) [] $
         collect
-        [ just $ mkCtor "new" []
+        [ just $ mkCtor "new" np
         , just $ mkMethod' "at" "at" [sizeT] $ refT t
         , just $ mkConstMethod' "at" "atConst" [sizeT] $ refT $ constT t
-        , just $ mkMethod' "back" "back" [] $ refT t
-        , just $ mkConstMethod' "back" "backConst" [] $ refT $ constT t
-        , just $ mkMethod' "begin" "begin" [] $ toGcT $ objT iterator
-        , just $ mkConstMethod' "begin" "beginConst" [] $ toGcT $ objT constIterator
-        , just $ mkConstMethod "capacity" [] sizeT
-        , just $ mkMethod "clear" [] voidT
-        , just $ mkConstMethod "empty" [] boolT
-        , just $ mkMethod' "end" "end" [] $ toGcT $ objT iterator
-        , just $ mkConstMethod' "end" "endConst" [] $ toGcT $ objT constIterator
+        , just $ mkMethod' "back" "back" np $ refT t
+        , just $ mkConstMethod' "back" "backConst" np $ refT $ constT t
+        , just $ mkMethod' "begin" "begin" np $ toGcT $ objT iterator
+        , just $ mkConstMethod' "begin" "beginConst" np $ toGcT $ objT constIterator
+        , just $ mkConstMethod "capacity" np sizeT
+        , just $ mkMethod "clear" np voidT
+        , just $ mkConstMethod "empty" np boolT
+        , just $ mkMethod' "end" "end" np $ toGcT $ objT iterator
+        , just $ mkConstMethod' "end" "endConst" np $ toGcT $ objT constIterator
         , just $ mkMethod' "erase" "erase" [objT iterator] voidT
         , just $ mkMethod' "erase" "eraseRange" [objT iterator, objT iterator] voidT
-        , just $ mkMethod' "front" "front" [] $ refT t
-        , just $ mkConstMethod' "front" "frontConst" [] $ refT $ constT t
+        , just $ mkMethod' "front" "front" np $ refT t
+        , just $ mkConstMethod' "front" "frontConst" np $ refT $ constT t
         , just $ mkMethod "insert" [objT iterator, t] $ toGcT $ objT iterator
-        , just $ mkConstMethod' "max_size" "maxSize" [] sizeT
-        , just $ mkMethod' "pop_back" "popBack" [] voidT
+        , just $ mkConstMethod' "max_size" "maxSize" np sizeT
+        , just $ mkMethod' "pop_back" "popBack" np voidT
         , just $ mkMethod' "push_back" "pushBack" [t] voidT
         , just $ mkMethod "reserve" [sizeT] voidT
         , just $ mkMethod' "resize" "resize" [sizeT] voidT
         , just $ mkMethod' "resize" "resizeWith" [sizeT, t] voidT
-        , test (activeCppVersion >= Cpp2011) $ mkMethod' "shrink_to_fit" "shrinkToFit" [] voidT
-        , just $ mkConstMethod "size" [] sizeT
+        , test (activeCppVersion >= Cpp2011) $ mkMethod' "shrink_to_fit" "shrinkToFit" np voidT
+        , just $ mkConstMethod "size" np sizeT
         , just $ mkMethod "swap" [refT $ objT vector] voidT
         ]
 
@@ -201,4 +212,4 @@
 -- | Converts an instantiation into a list of exports to be included in a
 -- module.
 toExports :: Contents -> [Export]
-toExports m = map (ExportClass . ($ m)) [c_vector, c_iterator, c_constIterator]
+toExports m = map (Export . ($ m)) [c_vector, c_iterator, c_constIterator]
diff --git a/src/Foreign/Hoppy/Generator/Std/Wstring.hs b/src/Foreign/Hoppy/Generator/Std/Wstring.hs
new file mode 100644
--- /dev/null
+++ b/src/Foreign/Hoppy/Generator/Std/Wstring.hs
@@ -0,0 +1,85 @@
+-- This file is part of Hoppy.
+--
+-- Copyright 2015-2019 Bryan Gardiner <bog@khumba.net>
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+--     http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+{-# LANGUAGE CPP #-}
+
+-- | Bindings for @std::wstring@.
+module Foreign.Hoppy.Generator.Std.Wstring (c_wstring) where
+
+#if !MIN_VERSION_base(4,8,0)
+import Data.Monoid (mconcat)
+#endif
+import Foreign.Hoppy.Generator.Language.Haskell (addExport, addImports, indent, sayLn)
+import Foreign.Hoppy.Generator.Spec
+import Foreign.Hoppy.Generator.Spec.Class (
+  Class,
+  ClassHaskellConversion (..),
+  classSetHaskellConversion,
+  makeClass,
+  mkCtor,
+  mkConstMethod,
+  mkConstMethod',
+  mkMethod',
+  )
+import Foreign.Hoppy.Generator.Types
+import Language.Haskell.Syntax (
+  HsName (HsIdent),
+  HsQName (UnQual),
+  HsType (HsTyCon),
+  )
+
+-- | @std::wstring@
+c_wstring :: Class
+c_wstring =
+  addReqIncludes [includeStd "string"] $
+  classAddFeatures [Assignable, Comparable, Copyable, Equatable] $
+  addAddendumHaskell addendum $
+  classSetHaskellConversion
+    ClassHaskellConversion
+      { classHaskellConversionType = Just $ do
+        addImports hsImportForPrelude
+        return $ HsTyCon $ UnQual $ HsIdent "HoppyP.String"
+      , classHaskellConversionToCppFn = Just $ do
+        addImports $ mconcat [hsImportForPrelude, hsImportForForeignC]
+        sayLn "HoppyP.flip HoppyFC.withCWStringLen stdWstring_newFromCWStringLen"
+      , classHaskellConversionFromCppFn = Just $ do
+        addImports $ mconcat [hsImport1 "Control.Applicative" "(<*)",
+                              hsImportForForeignC,
+                              hsImportForPrelude,
+                              hsImportForRuntime]
+        sayLn "\\s -> do"
+        indent $ do
+          sayLn "p <- stdWstring_data s"
+          sayLn "n <- stdWstring_size s"
+          sayLn "HoppyFC.peekCWStringLen (p, HoppyP.fromIntegral n) <* HoppyFHR.touchCppPtr s"
+      } $
+  makeClass (ident1 "std" "wstring") (Just $ toExtName "StdWstring") []
+  [ mkCtor "new" np
+  , mkCtor "newFromCWString" [ptrT $ constT wcharT]
+  , mkCtor "newFromCWStringLen_raw" [ptrT $ constT wcharT, sizeT]
+  , mkMethod' "at" "at" [intT] $ refT wcharT
+  , mkConstMethod' "at" "get" [intT] wcharT
+  , mkConstMethod "c_str" np $ ptrT $ constT wcharT
+  , mkConstMethod "data" np $ ptrT $ constT wcharT
+  , mkConstMethod "size" np sizeT
+  ]
+  where
+    addendum = do
+      addImports $ mconcat [hsImportForPrelude, hsImportForForeignC]
+      addExport "stdWstring_newFromCWStringLen"
+      sayLn "stdWstring_newFromCWStringLen :: HoppyFC.CWStringLen -> HoppyP.IO StdWstring"
+      sayLn "stdWstring_newFromCWStringLen (p,n) ="
+      indent $ sayLn "stdWstring_newFromCWStringLen_raw p (HoppyP.fromIntegral n)"
