-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | C++ FFI generator - Code generator
--   
--   Hoppy generates Haskell bindings to C++ libraries.
--   
--   This package is the code generator.
@package hoppy-generator
@version 0.3.3


-- | Utilities for conditional compilation of parts of interfaces.
--   
--   This module provides wrappers around <a>Maybe</a> and <a>catMaybes</a>
--   so that you can write code such as:
--   
--   <pre>
--   myClass =
--     makeClass ...
--     [ ...ctors... ] $
--     collect
--     [ just $ mkMethod "foo" ...
--     , test (apiVersion &gt;= [1, 2]) $ mkMethod "bar" ...
--     , test featureBaz $ mkMethod "baz" ...
--     ]
--   </pre>
module Foreign.Hoppy.Generator.Version

-- | Placeholder <a>Maybe</a>-like type that may be more general in the
--   future.
type Filtered = Maybe

-- | Filters a list of <a>Filtered</a> values down to the elements that are
--   actually present.
collect :: [Filtered a] -> [a]

-- | A <a>Filtered</a> value that is always absent.
none :: Filtered a

-- | Returns a <a>Filtered</a> value that is always present.
just :: a -> Filtered a

-- | Returns a <a>Filtered</a> value that is only present if the boolean is
--   true.
test :: Bool -> a -> Filtered a

-- | Versions of the C++ standard.
data CppVersion
Cpp1998 :: CppVersion
Cpp2011 :: CppVersion
Cpp2014 :: CppVersion

-- | The <a>CppVersion</a> chosen when one is not explicitly requested.
--   This is <a>Cpp2011</a>.
defaultCppVersion :: CppVersion

-- | The active version of the C++ standard. This looks to the
--   <tt>HOPPY_CPP_STD</tt> environment variable, and accepts the values
--   <tt>c++98</tt>, <tt>c++11</tt>, and <tt>c++14</tt>, which map to the
--   corresponding <a>CppVersion</a> values. If a value other than these is
--   set, then a warning is printed and the default is used. If no value is
--   set, the default is used.
--   
--   This uses <a>unsafePerformIO</a> internally and won't cope with a
--   changing environment.
activeCppVersion :: CppVersion
instance GHC.Show.Show Foreign.Hoppy.Generator.Version.CppVersion
instance GHC.Classes.Ord Foreign.Hoppy.Generator.Version.CppVersion
instance GHC.Classes.Eq Foreign.Hoppy.Generator.Version.CppVersion
instance GHC.Enum.Enum Foreign.Hoppy.Generator.Version.CppVersion
instance GHC.Enum.Bounded Foreign.Hoppy.Generator.Version.CppVersion


-- | Concrete C++ types. It is possible to represent invalid C++ types with
--   these functions, but we try to catch these and fail cleanly as much as
--   possible.
module Foreign.Hoppy.Generator.Types

-- | C++ <tt>void</tt>, Haskell <tt>()</tt>.
voidT :: Type

-- | C++ <tt>bool</tt>, Haskell <a>Bool</a>.
boolT :: Type

-- | C++ <tt>char</tt>, Haskell <a>CChar</a>.
charT :: Type

-- | C++ <tt>unsigned char</tt>, Haskell <a>CUChar</a>.
ucharT :: Type

-- | C++ <tt>short int</tt>, Haskell <a>CShort</a>.
shortT :: Type

-- | C++ <tt>unsigned short int</tt>, Haskell <a>CUShort</a>.
ushortT :: Type

-- | C++ <tt>int</tt>, Haskell <a>CInt</a>.
intT :: Type

-- | C++ <tt>unsigned int</tt>, Haskell <a>CUInt</a>.
uintT :: Type

-- | C++ <tt>long int</tt>, Haskell <a>CLong</a>.
longT :: Type

-- | C++ <tt>unsigned long int</tt>, Haskell <a>CULong</a>.
ulongT :: Type

-- | C++ <tt>long long int</tt>, Haskell <a>CLLong</a>.
llongT :: Type

-- | C++ <tt>unsigned long long int</tt>, Haskell <a>CULLong</a>.
ullongT :: Type

-- | C++ <tt>float</tt>, Haskell <a>CFloat</a>.
floatT :: Type

-- | C++ <tt>double</tt>, Haskell <a>CDouble</a>.
doubleT :: Type

-- | C++ <tt>int8_t</tt>, Haskell <a>Int8</a>.
int8T :: Type

-- | C++ <tt>int16_t</tt>, Haskell <a>Int16</a>.
int16T :: Type

-- | C++ <tt>int32_t</tt>, Haskell <a>Int32</a>.
int32T :: Type

-- | C++ <tt>int64_t</tt>, Haskell <a>Int64</a>.
int64T :: Type

-- | C++ <tt>uint8_t</tt>, Haskell <a>Word8</a>.
word8T :: Type

-- | C++ <tt>uint16_t</tt>, Haskell <a>Word16</a>.
word16T :: Type

-- | C++ <tt>uint32_t</tt>, Haskell <a>Word32</a>.
word32T :: Type

-- | C++ <tt>uint64_t</tt>, Haskell <a>Word64</a>.
word64T :: Type

-- | C++ <tt>ptrdiff_t</tt>, Haskell <a>CPtrdiff</a>.
ptrdiffT :: Type

-- | C++ <tt>size_t</tt>, Haskell <a>CSize</a>.
sizeT :: Type

-- | C++ <tt>ssize_t</tt>, Haskell <a>CSsize</a>.
ssizeT :: Type

-- | A C++ <tt>enum</tt> value.
enumT :: CppEnum -> Type

-- | A C++ bitspace value.
bitspaceT :: Bitspace -> Type

-- | A pointer to another type.
ptrT :: Type -> Type

-- | A reference to another type.
refT :: Type -> Type

-- | A function taking parameters and returning a value (or <a>voidT</a>).
--   Function pointers must wrap a <a>fnT</a> in a <a>ptrT</a>.
fnT :: [Type] -> Type -> Type

-- | A handle for calling foreign code from C++.
callbackT :: Callback -> Type

-- | An instance of a class. When used in a parameter or return type and
--   not wrapped in a <a>ptrT</a> or <a>refT</a>, this is a by-value
--   object.
objT :: Class -> Type

-- | A special case of <a>objT</a> that is only allowed when passing
--   objects from C++ to a foreign language. Rather than looking at the
--   object's <a>ClassConversion</a>, the object will be copied to the
--   heap, and a pointer to the heap object will be passed. The object must
--   be copy-constructable.
--   
--   <b>The foreign language owns the pointer, even for callback
--   arguments.</b>
objToHeapT :: Class -> Type

-- | This type transfers ownership of the object to the foreign language's
--   garbage collector, and results in a managed pointer in the foreign
--   language. This may only be used in one of the forms below, when
--   passing data from C++ to a foreign language (i.e. in a C++ function
--   return type or in a callback argument). In the first case, the
--   temporary object is copied to the heap, and the result is a managed
--   pointer to the heap object instead of the temporary.
--   
--   <ul>
--   <li><pre><a>toGcT</a> (<a>objT</a> cls)</pre></li>
--   <li><pre><a>toGcT</a> (<a>refT</a> (<a>constT</a> (<a>objT</a>
--   cls)))</pre></li>
--   <li><pre><a>toGcT</a> (<a>refT</a> (<a>objT</a> cls))</pre></li>
--   <li><pre><a>toGcT</a> (<a>ptrT</a> (<a>constT</a> (<a>objT</a>
--   cls)))</pre></li>
--   <li><pre><a>toGcT</a> (<a>ptrT</a> (<a>objT</a> cls))</pre></li>
--   </ul>
toGcT :: Type -> Type

-- | A <tt>const</tt> version of another type.
constT :: Type -> Type


-- | Shared portion of the Haskell code generator. Usable by binding
--   definitions.
module Foreign.Hoppy.Generator.Language.Haskell

-- | Indicates who is managing the lifetime of an object via an object
--   pointer.
data Managed

-- | The object's lifetime is being managed manually.
Unmanaged :: Managed

-- | The object's lifetime is being managed by the Haskell garbage
--   collector.
Managed :: Managed

-- | Returns the complete Haskell module name for a <a>Module</a> in an
--   <a>Interface</a>, taking into account the
--   <a>interfaceHaskellModuleBase</a> and the <a>moduleHaskellName</a>.
getModuleName :: Interface -> Module -> String

-- | Performs case conversions on the given string to ensure that it is a
--   valid component of a Haskell module name.
toModuleName :: String -> String

-- | A partially-rendered <a>Module</a>. Contains all of the module's
--   bindings, but may be subject to further processing.
data Partial
Partial :: String -> Output -> Partial

-- | This is just the module name.
[partialModuleHsName] :: Partial -> String
[partialOutput] :: Partial -> Output

-- | A chunk of generated Haskell code, including information about imports
--   and exports.
data Output
Output :: [HsExport] -> HsImportSet -> [String] -> Set String -> Output

-- | Haskell module exports. Each <a>HsExport</a> should include one item
--   to go in the export list of the generated module. Should only contain
--   objects imported or defined in the same <a>Output</a>.
[outputExports] :: Output -> [HsExport]

-- | Haskell module imports. Should include all imports needed for the
--   <a>outputBody</a>.
[outputImports] :: Output -> HsImportSet

-- | Lines of Haskell code (possibly empty). These lines may not contain
--   the newline character in them. There is an implicit newline between
--   each string, as given by <tt>intercalate "\n" . outputBody</tt>.
[outputBody] :: Output -> [String]

-- | Language extensions to enable via the <tt>{--}</tt> pragma for the
--   whole module.
[outputExtensions] :: Output -> Set String

-- | A generator monad for Haskell code.
--   
--   Errors thrown in this monad are of the form:
--   
--   <pre>
--   "$problem; $context; $moreContext; $evenMoreContext."
--   </pre>
--   
--   For example, "Class Foo is not convertible (use
--   classModifyConversion); generating function bar; in module baz.".
--   
--   The main error message given to <a>throwError</a> should be
--   capitalized and should not end with punctuation. If there is a
--   suggestion, include it in parentheses at the end of the message.
--   <a>withErrorContext</a> and <a>inFunction</a> add context information,
--   and should be given clauses, without punctuation.
type Generator = ReaderT Env (WriterT Output (Except ErrorMsg))

-- | Runs a generator action for the given interface and module name
--   string. Returns an error message if an error occurred, otherwise the
--   action's output together with its value.
runGenerator :: Interface -> Module -> Generator a -> Either ErrorMsg (Partial, a)

-- | Runs a generator action and returns the its value.
evalGenerator :: Interface -> Module -> Generator a -> Either ErrorMsg a

-- | Runs a generator action and returns its output.
execGenerator :: Interface -> Module -> Generator a -> Either ErrorMsg Partial

-- | Converts a <a>Partial</a> into a complete Haskell module.
renderPartial :: Partial -> String

-- | Returns the currently generating interface.
askInterface :: Generator Interface

-- | Returns the currently generating module.
askModule :: Generator Module

-- | Returns the currently generating module's Haskell module name.
askModuleName :: Generator String

-- | Looks up the <a>Module</a> containing a given external name, throwing
--   an error if it can't be found.
getModuleForExtName :: ExtName -> Generator Module

-- | Adds context information to the end of any error message thrown by the
--   action. See <a>Generator</a>.
withErrorContext :: String -> Generator a -> Generator a

-- | Adds the given function name to any error message thrown by the
--   action, for context.
inFunction :: String -> Generator a -> Generator a

-- | Indicates strings that represent an item in a Haskell module export
--   list.
type HsExport = String

-- | Adds an export to the current module.
addExport :: HsExport -> Generator ()

-- | <tt>addExport' "x"</tt> adds an export of the form <tt>x (..)</tt> to
--   the current module.
addExport' :: HsExport -> Generator ()

-- | Adds multiple exports to the current module.
addExports :: [HsExport] -> Generator ()

-- | Adds imports to the current module.
addImports :: HsImportSet -> Generator ()

-- | Adds a Haskell language extension to the current module.
addExtension :: String -> Generator ()

-- | Outputs a line of Haskell code. A newline will be added on the end of
--   the input. Newline characters must not be given to this function.
sayLn :: String -> Generator ()

-- | Outputs multiple words to form a line of Haskell code (effectively
--   <tt>saysLn = sayLn . concat</tt>).
saysLn :: [String] -> Generator ()

-- | Outputs an empty line of Haskell code. This is reportedly valid Perl
--   code as well.
ln :: Generator ()

-- | Runs the given action, indenting all code output by the action one
--   level.
indent :: Generator a -> Generator a

-- | Runs the given action, indenting all code output by the action N
--   spaces.
indentSpaces :: Int -> Generator a -> Generator a

-- | Takes a list of binding actions and a body action, and outputs a
--   <tt>let</tt> expression. By passing in <a>Nothing</a> for the body, it
--   will be omitted, so <tt>let</tt> statements in <tt>do</tt> blocks can
--   be created as well. Output is of the form:
--   
--   <pre>
--   let
--     &lt;binding1&gt;
--     ...
--     &lt;bindingN&gt;
--     in
--       &lt;body&gt;
--   </pre>
--   
--   To stretch a binding over multiple lines, lines past the first should
--   use <a>indent</a> manually.
sayLet :: [Generator ()] -> Maybe (Generator ()) -> Generator ()

-- | Returns the Haskell name for an enum.
toHsEnumTypeName :: CppEnum -> Generator String

-- | Pure version of <a>toHsEnumTypeName</a> that doesn't create a
--   qualified name.
toHsEnumTypeName' :: CppEnum -> String

-- | Constructs the data constructor name for a value in an enum. Like C++
--   and unlike say Java, Haskell enum values aren't in a separate
--   enum-specific namespace, so we prepend the enum name to the value name
--   to get the data constructor name. The value name is a list of words;
--   see <a>enumValueNames</a>.
toHsEnumCtorName :: CppEnum -> [String] -> Generator String

-- | Pure version of <a>toHsEnumCtorName</a> that doesn't create a
--   qualified name.
toHsEnumCtorName' :: CppEnum -> [String] -> String

-- | Returns the Haskell name for a bitspace. See <a>toHsEnumTypeName</a>.
toHsBitspaceTypeName :: Bitspace -> Generator String

-- | Pure version of <a>toHsBitspaceTypeName</a> that doesn't create a
--   qualified name.
toHsBitspaceTypeName' :: Bitspace -> String

-- | Constructs the data constructor name for a value in a bitspace. See
--   <a>toHsEnumCtorName</a>.
toHsBitspaceValueName :: Bitspace -> [String] -> Generator String

-- | Pure version of <a>toHsBitspaceValueName</a> that doesn't create a
--   qualified name.
toHsBitspaceValueName' :: Bitspace -> [String] -> String

-- | Returns the name of the function that will convert a bitspace value
--   into a raw numeric value.
toHsBitspaceToNumName :: Bitspace -> Generator String

-- | Pure version of <a>toHsBitspaceToNumName</a> that doesn't create a
--   qualified name.
toHsBitspaceToNumName' :: Bitspace -> String

-- | The name of the Haskell typeclass that contains a method for
--   converting to a bitspace value.
toHsBitspaceClassName :: Bitspace -> Generator String

-- | Pure version of <a>toHsBitspaceClassName</a> that doesn't create a
--   qualified name.
toHsBitspaceClassName' :: Bitspace -> String

-- | The name of the method in the <a>toHsBitspaceClassName</a> typeclass
--   that constructs bitspace values.
toHsBitspaceFromValueName :: Bitspace -> Generator String

-- | Pure version of <a>toHsBitspaceFromValueName</a> that doesn't create a
--   qualified name.
toHsBitspaceFromValueName' :: Bitspace -> String

-- | The name for the typeclass of types that can be represented as values
--   of the given C++ class.
toHsValueClassName :: Class -> Generator String

-- | Pure version of <a>toHsValueClassName</a> that doesn't create a
--   qualified name.
toHsValueClassName' :: Class -> String

-- | The name of the method within the <a>toHsValueClassName</a> typeclass
--   for accessing an object of the type as a pointer.
toHsWithValuePtrName :: Class -> Generator String

-- | Pure version of <a>toHsWithValuePtrName</a> that doesn't create a
--   qualified name.
toHsWithValuePtrName' :: Class -> String

-- | The name for the typeclass of types that are (possibly const) pointers
--   to objects of the given C++ class, or subclasses.
toHsPtrClassName :: Constness -> Class -> Generator String

-- | Pure version of <a>toHsPtrClassName</a> that doesn't create a
--   qualified name.
toHsPtrClassName' :: Constness -> Class -> String

-- | The name of the function that upcasts pointers to the specific class
--   type and constness.
toHsCastMethodName :: Constness -> Class -> Generator String

-- | Pure version of <a>toHsCastMethodName</a> that doesn't create a
--   qualified name.
toHsCastMethodName' :: Constness -> Class -> String

-- | The name of the typeclass that provides a method to downcast to a
--   specific class type. See <a>toHsDownCastMethodName</a>.
toHsDownCastClassName :: Constness -> Class -> Generator String

-- | Pure version of <a>toHsDownCastClassName</a> that doesn't create a
--   qualified name.
toHsDownCastClassName' :: Constness -> Class -> String

-- | The name of the function that downcasts pointers to the specific class
--   type and constness.
toHsDownCastMethodName :: Constness -> Class -> Generator String

-- | Pure version of <a>toHsDownCastMethodName</a> that doesn't create a
--   qualified name.
toHsDownCastMethodName' :: Constness -> Class -> String

-- | The import name for the foreign function that casts between two
--   specific pointer types. Used for upcasting and downcasting.
--   
--   We need to know which module the cast function resides in, and while
--   we could look this up, the caller always knows, so we just have them
--   pass it in.
toHsCastPrimitiveName :: Class -> Class -> Class -> Generator String

-- | Pure version of <a>toHsCastPrimitiveName</a> that doesn't create a
--   qualified name.
toHsCastPrimitiveName' :: Class -> Class -> String

-- | The name of one of the functions that add<i>remove const to</i>from a
--   class's pointer type. Given <a>Const</a>, it will return the function
--   that adds const, and given <a>Nonconst</a>, it will return the
--   function that removes const.
toHsConstCastFnName :: Constness -> Class -> Generator String

-- | Pure version of <a>toHsConstCastFnName</a> that doesn't create a
--   qualified name.
toHsConstCastFnName' :: Constness -> Class -> String

-- | The name of the data type that represents a pointer to an object of
--   the given class and constness.
toHsDataTypeName :: Constness -> Class -> Generator String

-- | Pure version of <a>toHsDataTypeName</a> that doesn't create a
--   qualified name.
toHsDataTypeName' :: Constness -> Class -> String

-- | The name of a data constructor for one of the object pointer types.
toHsDataCtorName :: Managed -> Constness -> Class -> Generator String

-- | Pure version of <a>toHsDataCtorName</a> that doesn't create a
--   qualified name.
toHsDataCtorName' :: Managed -> Constness -> Class -> String

-- | The name of the foreign function import wrapping <tt>delete</tt> for
--   the given class type. This is in internal to the binding; normal users
--   should use <a>delete</a>.
--   
--   This is internal to a generated Haskell module, so it does not have a
--   public (qualified) form.
toHsClassDeleteFnName' :: Class -> String

-- | The name of the foreign import that imports the same function as
--   <tt>toHsClassDeleteFnName</tt>, but as a <a>FunPtr</a> rather than an
--   actual function.
--   
--   This is internal to a generated Haskell module, so it does not have a
--   public (qualified) form.
toHsClassDeleteFnPtrName' :: Class -> String

-- | Returns the name of the Haskell function that invokes the given
--   constructor.
toHsCtorName :: Class -> Ctor -> Generator String

-- | Pure version of <a>toHsCtorName</a> that doesn't create a qualified
--   name.
toHsCtorName' :: Class -> Ctor -> String

-- | Returns the name of the Haskell function that invokes the given
--   method.
toHsMethodName :: Class -> Method -> Generator String

-- | Pure version of <a>toHsMethodName</a> that doesn't create a qualified
--   name.
toHsMethodName' :: Class -> Method -> String

-- | Returns the name of the Haskell function for an entity in a class.
toHsClassEntityName :: IsFnName String name => Class -> name -> Generator String

-- | Pure version of <a>toHsClassEntityName</a> that doesn't create a
--   qualified name.
toHsClassEntityName' :: IsFnName String name => Class -> name -> String

-- | The name of the function that takes a Haskell function and wraps it in
--   a callback object. This is internal to the binding; normal users can
--   pass Haskell functions to be used as callbacks inplicitly.
toHsCallbackCtorName :: Callback -> Generator String

-- | Pure version of <a>toHsCallbackCtorName</a> that doesn't create a
--   qualified name.
toHsCallbackCtorName' :: Callback -> String

-- | The name of the function that takes a Haskell function with
--   Haskell-side types and wraps it in a <a>FunPtr</a> that does
--   appropriate conversions to and from C-side types.
toHsCallbackNewFunPtrFnName :: Callback -> Generator String

-- | Pure version of <a>toHsCallbackNewFunPtrFnName</a> that doesn't create
--   a qualified name.
toHsCallbackNewFunPtrFnName' :: Callback -> String

-- | Converts an external name into a name suitable for a Haskell function
--   or variable.
toHsFnName :: ExtName -> Generator String

-- | Pure version of <a>toHsFnName</a> that doesn't create a qualified
--   name.
toHsFnName' :: ExtName -> String

-- | Returns a distinct argument variable name for each nonnegative number.
toArgName :: Int -> String

-- | The Haskell side of bindings performs conversions between C FFI types
--   and Haskell types. This denotes which side's type is being used.
data HsTypeSide

-- | The C type sent from C++.
HsCSide :: HsTypeSide

-- | The Haskell-native type.
HsHsSide :: HsTypeSide

-- | Returns the <a>HsType</a> corresponding to a <a>Type</a>, and also
--   adds imports to the <a>Generator</a> as necessary for Haskell types
--   that the <a>Type</a> references. On failure, an error is thrown.
cppTypeToHsTypeAndUse :: HsTypeSide -> Type -> Generator HsType

-- | Returns the <a>ClassHaskellConversion</a> of a class.
getClassHaskellConversion :: Class -> ClassHaskellConversion

-- | Constructs the function type for a callback. For Haskell, the type
--   depends on the side; the C++ side has additional parameters.
--   
--   Keep this in sync with the C++ generator's version.
callbackToTFn :: HsTypeSide -> Callback -> Generator Type

-- | Prints a value like <a>prettyPrint</a>, but removes newlines so that
--   they don't cause problems with this module's textual generation.
--   Should be mainly used for printing types; stripping newlines from
--   definitions for example could go badly.
prettyPrint :: Pretty a => a -> String
instance GHC.Show.Show Foreign.Hoppy.Generator.Language.Haskell.HsTypeSide
instance GHC.Classes.Eq Foreign.Hoppy.Generator.Language.Haskell.HsTypeSide
instance GHC.Classes.Ord Foreign.Hoppy.Generator.Language.Haskell.Managed
instance GHC.Classes.Eq Foreign.Hoppy.Generator.Language.Haskell.Managed
instance GHC.Enum.Enum Foreign.Hoppy.Generator.Language.Haskell.Managed
instance GHC.Enum.Bounded Foreign.Hoppy.Generator.Language.Haskell.Managed
instance GHC.Classes.Eq Foreign.Hoppy.Generator.Language.Haskell.Partial
instance GHC.Classes.Ord Foreign.Hoppy.Generator.Language.Haskell.Partial
instance GHC.Base.Monoid Foreign.Hoppy.Generator.Language.Haskell.Output


-- | Bindings for common class operations, such as copy construction.
module Foreign.Hoppy.Generator.Spec.ClassFeature

-- | Sets of functionality that can be stamped onto a class with
--   <a>classAddFeatures</a>.
data ClassFeature

-- | Provides the assignment operator, <tt>Foo&amp; Foo::operator=(const
--   Foo&amp;)</tt>.
Assignable :: ClassFeature

-- | Provides operators <tt>&lt;</tt>, <tt>&lt;=</tt>, <tt>&gt;</tt>,
--   <tt>&gt;=</tt>, for example <tt>bool Foo::operator&lt;(const
--   Foo&amp;)</tt>. This feature does not automatically include
--   <a>Equatable</a>.
Comparable :: ClassFeature

-- | Provides copy construction, <tt>Foo::Foo(const Foo&amp;)</tt>.
Copyable :: ClassFeature

-- | Provides <tt>operator==</tt> and <tt>operator!=</tt>, for example
--   <tt>bool Foo::operator==(const Foo&amp;)</tt>.
Equatable :: ClassFeature

-- | Adds the contents of a feature to a class. Does not check for overlap
--   with existing class contents.
classAddFeatures :: [ClassFeature] -> Class -> Class
instance GHC.Show.Show Foreign.Hoppy.Generator.Spec.ClassFeature.ClassFeature
instance GHC.Classes.Eq Foreign.Hoppy.Generator.Spec.ClassFeature.ClassFeature


-- | The primary data types for specifying C++ interfaces.
--   
--   <a>Show</a> instances in this module produce strings of the form
--   <tt>"&lt;TypeOfObject nameOfObject otherInfo...&gt;"</tt>. They can be
--   used in error messages without specifying a noun separately, i.e.
--   write <tt>show cls</tt> instead of <tt>"the class " ++ show cls</tt>.
module Foreign.Hoppy.Generator.Spec

-- | A complete specification of a C++ API. Generators for different
--   languages, including the binding generator for C++, use these to
--   produce their output.
--   
--   <a>Interface</a> does not have a <a>HandlesExceptions</a> instance
--   because <a>modifyExceptionHandlers</a> does not work for it (handled
--   exceptions cannot be modified after an <a>Interface</a> is
--   constructed).
data Interface

-- | Indicates strings that are error messages.
type ErrorMsg = String

-- | Optional parameters when constructing an <a>Interface</a> with
--   <a>interface</a>.
data InterfaceOptions
InterfaceOptions :: ExceptionHandlers -> InterfaceOptions
[interfaceOptionsExceptionHandlers] :: InterfaceOptions -> ExceptionHandlers

-- | Options used by <a>interface</a>. This contains no exception handlers.
defaultInterfaceOptions :: InterfaceOptions

-- | Constructs an <a>Interface</a> from the required parts. Some
--   validation is performed; if the resulting interface would be invalid,
--   an error message is returned instead.
--   
--   This function passes <a>defaultInterfaceOptions</a> to
--   <a>interface'</a>.
interface :: String -> [Module] -> Either ErrorMsg Interface

-- | Same as <a>interface</a>, but accepts some optional arguments.
interface' :: String -> [Module] -> InterfaceOptions -> Either ErrorMsg Interface

-- | The textual name of the interface.
interfaceName :: Interface -> String

-- | All of the individual modules, by <a>moduleName</a>.
interfaceModules :: Interface -> Map String Module

-- | Maps each <a>ExtName</a> exported by some module to the module that
--   exports the name.
interfaceNamesToModules :: Interface -> Map ExtName Module

-- | The name of the parent Haskell module under which a Haskell module
--   will be generated for a Hoppy <a>Module</a>. This is a list of Haskell
--   module path components, in other words, <tt><a>intercalate</a>
--   "."</tt> on the list produces a Haskell module name. Defaults to
--   <a>interfaceDefaultHaskellModuleBase</a>, and may be overridden with
--   <a>interfaceAddHaskellModuleBase</a>.
interfaceHaskellModuleBase :: Interface -> [String]

-- | The default Haskell module under which Hoppy modules will be
--   generated. This is <tt>Foreign.Hoppy.Generated</tt>, that is:
--   
--   <pre>
--   ["Foreign", "Hoppy", "Generated"]
--   </pre>
interfaceDefaultHaskellModuleBase :: [String]

-- | Sets an interface to generate all of its modules under the given
--   Haskell module prefix. See <a>interfaceHaskellModuleBase</a>.
interfaceAddHaskellModuleBase :: [String] -> Interface -> Either String Interface

-- | Short qualified module import names that generated modules use to
--   refer to each other tersely.
interfaceHaskellModuleImportNames :: Interface -> Map Module String

-- | Exceptions that all functions in the interface may throw.
interfaceExceptionHandlers :: Interface -> ExceptionHandlers

-- | Whether callbacks within the interface support throwing C++ exceptions
--   from Haskell into C++ during their execution. This may be overridden
--   by <a>moduleCallbacksThrow</a> and <a>callbackThrows</a>.
interfaceCallbacksThrow :: Interface -> Bool

-- | Changes <a>callbackThrows</a> for all callbacks in an interface that
--   don't have it set explicitly at the module or callback level.
interfaceSetCallbacksThrow :: Bool -> Interface -> Interface

-- | Returns the the exception ID for a class in an interface, if it has
--   one (i.e. if it's been marked as an exception class with
--   <a>classMakeException</a>).
interfaceExceptionClassId :: Interface -> Class -> Maybe ExceptionId

-- | When an interface uses C++ exceptions, then one module needs to
--   manually be selected to contain some interface-specific runtime
--   support. This is the selected module.
interfaceExceptionSupportModule :: Interface -> Maybe Module

-- | Sets an interface's exception support module, for interfaces that use
--   exceptions.
interfaceSetExceptionSupportModule :: Module -> Interface -> Interface

-- | An <tt>#include</tt> directive in a C++ file.
data Include

-- | Creates an <tt>#include &lt;...&gt;</tt> directive.
includeStd :: String -> Include

-- | Creates an <tt>#include "..."</tt> directive.
includeLocal :: String -> Include

-- | Returns the complete <tt>#include ...</tt> line for an include,
--   including trailing newline.
includeToString :: Include -> String

-- | A portion of functionality in a C++ API. An <a>Interface</a> is
--   composed of multiple modules. A module will generate a single
--   compilation unit containing bindings for all of the module's exports.
--   The C++ code for a generated module will <tt>#include</tt> everything
--   necessary for what is written to the header and source files
--   separately. You can declare include dependencies with e.g.
--   <a>addReqIncludes</a>, either for individual exports or at the module
--   level. Dependencies between modules are handled automatically, and
--   circularity is supported to a certain extent. See the documentation
--   for the individual language modules for further details.
data Module

-- | The module's name. A module name must identify a unique module within
--   an <a>Interface</a>.
moduleName :: Module -> String

-- | A relative path under a C++ sources root to which the generator will
--   write a header file for the module's C++ bindings.
moduleHppPath :: Module -> String

-- | A relative path under a C++ sources root to which the generator will
--   write a source file for the module's C++ bindings.
moduleCppPath :: Module -> String

-- | All of the exports in a module.
moduleExports :: Module -> Map ExtName Export

-- | Module-level requirements.
moduleReqs :: Module -> Reqs

-- | Exceptions that all functions in the module may throw.
moduleExceptionHandlers :: Module -> ExceptionHandlers

-- | Whether callbacks exported from the module support exceptions being
--   thrown during their execution. When present, this overrides
--   <a>interfaceCallbacksThrow</a>. This maybe overridden by
--   <a>callbackThrows</a>.
moduleCallbacksThrow :: Module -> Maybe Bool

-- | Changes <a>callbackThrows</a> for all callbacks in a module that don't
--   have it set explicitly.
moduleSetCallbacksThrow :: MonadState Module m => Maybe Bool -> m ()

-- | The module's addendum.
moduleAddendum :: Module -> Addendum

-- | The generated Haskell module name, underneath the
--   <a>interfaceHaskellModuleBase</a>. If absent (by default), the
--   <a>moduleName</a> is used. May be modified with
--   <a>moduleAddHaskellName</a>.
moduleHaskellName :: Module -> Maybe [String]

-- | Creates an empty module, ready to be configured with
--   <a>moduleModify</a>.
makeModule :: String -> String -> String -> Module

-- | Extends a module. To be used with the module state-monad actions in
--   this package.
moduleModify :: Module -> StateT Module (Either String) () -> Either ErrorMsg Module

-- | Same as <a>moduleModify</a>, but calls <a>error</a> in the case of
--   failure, which is okay in for a generator which would abort in this
--   case anyway.
moduleModify' :: Module -> StateT Module (Either String) () -> Module

-- | Replaces a module's <a>moduleHppPath</a>.
moduleSetHppPath :: MonadState Module m => String -> m ()

-- | Replaces a module's <a>moduleCppPath</a>.
moduleSetCppPath :: MonadState Module m => String -> m ()

-- | Adds exports to a module. An export must only be added to any module
--   at most once, and must not be added to multiple modules.
moduleAddExports :: (MonadError String m, MonadState Module m) => [Export] -> m ()

-- | Changes a module's <a>moduleHaskellName</a> from the default. This can
--   only be called once on a module.
moduleAddHaskellName :: (MonadError String m, MonadState Module m) => [String] -> m ()

-- | A set of requirements of needed to use an identifier in C++ (function,
--   type, etc.), via a set of <a>Include</a>s. The monoid instance has
--   <a>mempty</a> as an empty set of includes, and <a>mappend</a> unions
--   two include sets.
data Reqs

-- | The includes specified by a <a>Reqs</a>.
reqsIncludes :: Reqs -> Set Include

-- | Creates a <a>Reqs</a> that contains the given include.
reqInclude :: Include -> Reqs

-- | C++ types that have requirements in order to use them in generated
--   bindings.
class HasReqs a where setReqs = modifyReqs . const modifyReqs f x = setReqs (f $ getReqs x) x

-- | Returns an object's requirements.
getReqs :: HasReqs a => a -> Reqs

-- | Replaces an object's requirements with new ones.
setReqs :: HasReqs a => Reqs -> a -> a

-- | Modifies an object's requirements.
modifyReqs :: HasReqs a => (Reqs -> Reqs) -> a -> a

-- | Adds to a object's requirements.
addReqs :: HasReqs a => Reqs -> a -> a

-- | Adds a list of includes to the requirements of an object.
addReqIncludes :: HasReqs a => [Include] -> a -> a

-- | An external name is a string that generated bindings use to uniquely
--   identify an object at runtime. An external name must start with an
--   alphabetic character, and may only contain alphanumeric characters and
--   <tt>'_'</tt>. You are free to use whatever naming style you like; case
--   conversions will be performed automatically when required. Hoppy does
--   make use of some conventions though, for example with <a>Operator</a>s
--   and in the provided bindings for the C++ standard library.
--   
--   External names must be unique within an interface. They may not be
--   reused between modules. This assumption is used for symbol naming in
--   compiled shared objects and to freely import modules in Haskell
--   bindings.
data ExtName

-- | Creates an <a>ExtName</a> that contains the given string, erroring if
--   the string is an invalid <a>ExtName</a>.
toExtName :: String -> ExtName

-- | Returns true if the given string is represents a valid <a>ExtName</a>.
isValidExtName :: String -> Bool

-- | Returns the string an an <a>ExtName</a> contains.
fromExtName :: ExtName -> String

-- | Types that have an external name, and also optionally have nested
--   entities with external names as well. See <a>getAllExtNames</a>.
class HasExtNames a where getNestedExtNames _ = []

-- | Returns the external name by which a given entity is referenced.
getPrimaryExtName :: HasExtNames a => a -> ExtName

-- | Returns external names nested within the given entity. Does not
--   include the primary external name.
getNestedExtNames :: HasExtNames a => a -> [ExtName]

-- | Returns a list of all of the external names an entity contains. This
--   combines both <a>getPrimaryExtName</a> and <a>getNestedExtNames</a>.
getAllExtNames :: HasExtNames a => a -> [ExtName]

-- | The C++ name of a function or method.
data FnName name

-- | A regular, "alphanumeric" name. The exact type depends on what kind of
--   object is being named.
FnName :: name -> FnName name

-- | An operator name.
FnOp :: Operator -> FnName name

-- | Enables implementing automatic conversions to a <tt><a>FnName</a>
--   t</tt>.
class IsFnName t a
toFnName :: IsFnName t a => a -> FnName t

-- | Overloadable C++ operators.
data Operator

-- | <pre>
--   x(...)
--   </pre>
OpCall :: Operator

-- | <pre>
--   x, y
--   </pre>
OpComma :: Operator

-- | <pre>
--   x = y
--   </pre>
OpAssign :: Operator

-- | <pre>
--   x[y]
--   </pre>
OpArray :: Operator

-- | <pre>
--   *x
--   </pre>
OpDeref :: Operator

-- | <pre>
--   &amp;x
--   </pre>
OpAddress :: Operator

-- | <pre>
--   x + y
--   </pre>
OpAdd :: Operator

-- | <pre>
--   x += y
--   </pre>
OpAddAssign :: Operator

-- | <pre>
--   x - y
--   </pre>
OpSubtract :: Operator

-- | <pre>
--   x -= y
--   </pre>
OpSubtractAssign :: Operator

-- | <pre>
--   x * y
--   </pre>
OpMultiply :: Operator

-- | <pre>
--   x *= y
--   </pre>
OpMultiplyAssign :: Operator

-- | <pre>
--   x / y
--   </pre>
OpDivide :: Operator

-- | <pre>
--   x /= y
--   </pre>
OpDivideAssign :: Operator

-- | <pre>
--   x % y
--   </pre>
OpModulo :: Operator

-- | <pre>
--   x %= y
--   </pre>
OpModuloAssign :: Operator

-- | <pre>
--   +x
--   </pre>
OpPlus :: Operator

-- | <pre>
--   -x
--   </pre>
OpMinus :: Operator

-- | <pre>
--   ++x
--   </pre>
OpIncPre :: Operator

-- | <pre>
--   x++
--   </pre>
OpIncPost :: Operator

-- | <pre>
--   --x
--   </pre>
OpDecPre :: Operator

-- | <pre>
--   x--
--   </pre>
OpDecPost :: Operator

-- | <pre>
--   x == y
--   </pre>
OpEq :: Operator

-- | <pre>
--   x != y
--   </pre>
OpNe :: Operator

-- | <pre>
--   x &lt; y
--   </pre>
OpLt :: Operator

-- | <pre>
--   x &lt;= y
--   </pre>
OpLe :: Operator

-- | <pre>
--   x &gt; y
--   </pre>
OpGt :: Operator

-- | <pre>
--   x &gt;= y
--   </pre>
OpGe :: Operator

-- | <pre>
--   !x
--   </pre>
OpNot :: Operator

-- | <pre>
--   x &amp;&amp; y
--   </pre>
OpAnd :: Operator

-- | <pre>
--   x || y
--   </pre>
OpOr :: Operator

-- | <pre>
--   ~x
--   </pre>
OpBitNot :: Operator

-- | <pre>
--   x &amp; y
--   </pre>
OpBitAnd :: Operator

-- | <pre>
--   x &amp;= y
--   </pre>
OpBitAndAssign :: Operator

-- | <pre>
--   x | y
--   </pre>
OpBitOr :: Operator

-- | <pre>
--   x |= y
--   </pre>
OpBitOrAssign :: Operator

-- | <pre>
--   x ^ y
--   </pre>
OpBitXor :: Operator

-- | <pre>
--   x ^= y
--   </pre>
OpBitXorAssign :: Operator

-- | <pre>
--   x &lt;&lt; y
--   </pre>
OpShl :: Operator

-- | <pre>
--   x &lt;&lt;= y
--   </pre>
OpShlAssign :: Operator

-- | <pre>
--   x &gt;&gt; y
--   </pre>
OpShr :: Operator

-- | <pre>
--   x &gt;&gt;= y
--   </pre>
OpShrAssign :: Operator

-- | The arity and syntax of an operator.
data OperatorType

-- | Prefix unary operators. Examples: <tt>!x</tt>, <tt>*x</tt>,
--   <tt>++x</tt>.
UnaryPrefixOperator :: String -> OperatorType

-- | Postfix unary operators. Examples: <tt>x--, x++</tt>.
UnaryPostfixOperator :: String -> OperatorType

-- | Infix binary operators. Examples: <tt>x * y</tt>, <tt>x &gt;&gt;=
--   y</tt>.
BinaryOperator :: String -> OperatorType

-- | <tt>x(...)</tt> with arbitrary arity.
CallOperator :: OperatorType

-- | <tt>x[y]</tt>, a binary operator with non-infix syntax.
ArrayOperator :: OperatorType

-- | Returns a conventional string to use for the <a>ExtName</a> of an
--   operator.
operatorPreferredExtName :: Operator -> ExtName

-- | Returns a conventional name for an operator, as with
--   <a>operatorPreferredExtName</a>, but as a string.
operatorPreferredExtName' :: Operator -> String

-- | Returns the type of an operator.
operatorType :: Operator -> OperatorType

-- | Specifies some C++ object (function or class) to give access to.
data Export

-- | Exports a variable.
ExportVariable :: Variable -> Export

-- | Exports an enum.
ExportEnum :: CppEnum -> Export

-- | Exports a bitspace.
ExportBitspace :: Bitspace -> Export

-- | Exports a function.
ExportFn :: Function -> Export

-- | Exports a class with all of its contents.
ExportClass :: Class -> Export

-- | Exports a callback.
ExportCallback :: Callback -> Export

-- | Returns the export's addendum. <a>Export</a> doesn't have a
--   <a>HasAddendum</a> instance because you normally wouldn't want to
--   modify the addendum of one.
exportAddendum :: Export -> Addendum

-- | A path to some C++ object, including namespaces. An identifier
--   consists of multiple parts separated by <tt>"::"</tt>. Each part has a
--   name string followed by an optional template argument list, where each
--   argument gets rendered from a <a>Type</a> (non-type arguments for
--   template metaprogramming are not supported).
data Identifier

-- | The separate parts of the identifier, between <tt>::</tt>s.
identifierParts :: Identifier -> [IdPart]

-- | A single component of an <a>Identifier</a>, between <tt>::</tt>s.
data IdPart

-- | The name within the enclosing scope.
idPartBase :: IdPart -> String

-- | Template arguments, if present.
idPartArgs :: IdPart -> Maybe [Type]

-- | Creates an identifier of the form <tt>a</tt>.
ident :: String -> Identifier

-- | Creates an identifier of the form <tt>a1::a2::...::aN</tt>.
ident' :: [String] -> Identifier

-- | Creates an identifier of the form <tt>a::b</tt>.
ident1 :: String -> String -> Identifier

-- | Creates an identifier of the form <tt>a::b::c</tt>.
ident2 :: String -> String -> String -> Identifier

-- | Creates an identifier of the form <tt>a::b::c::d</tt>.
ident3 :: String -> String -> String -> String -> Identifier

-- | Creates an identifier of the form <tt>a::b::c::d::e</tt>.
ident4 :: String -> String -> String -> String -> String -> Identifier

-- | Creates an identifier of the form <tt>a::b::c::d::e::f</tt>.
ident5 :: String -> String -> String -> String -> String -> String -> Identifier

-- | Creates an identifier of the form <tt>a&lt;...&gt;</tt>.
identT :: String -> [Type] -> Identifier

-- | Creates an identifier with arbitrary many templated and non-templated
--   parts.
identT' :: [(String, Maybe [Type])] -> Identifier

-- | Creates an identifier of the form <tt>a::b&lt;...&gt;</tt>.
ident1T :: String -> String -> [Type] -> Identifier

-- | Creates an identifier of the form <tt>a::b::c&lt;...&gt;</tt>.
ident2T :: String -> String -> String -> [Type] -> Identifier

-- | Creates an identifier of the form <tt>a::b::c::d&lt;...&gt;</tt>.
ident3T :: String -> String -> String -> String -> [Type] -> Identifier

-- | Creates an identifier of the form <tt>a::b::c::d::e&lt;...&gt;</tt>.
ident4T :: String -> String -> String -> String -> String -> [Type] -> Identifier

-- | Creates an identifier of the form
--   <tt>a::b::c::d::e::f&lt;...&gt;</tt>.
ident5T :: String -> String -> String -> String -> String -> String -> [Type] -> Identifier

-- | A concrete C++ type. Use the bindings in
--   <a>Foreign.Hoppy.Generator.Types</a> for values of this type; these
--   data constructors are subject to change without notice.
data Type
Internal_TVoid :: Type
Internal_TBool :: Type
Internal_TChar :: Type
Internal_TUChar :: Type
Internal_TShort :: Type
Internal_TUShort :: Type
Internal_TInt :: Type
Internal_TUInt :: Type
Internal_TLong :: Type
Internal_TULong :: Type
Internal_TLLong :: Type
Internal_TULLong :: Type
Internal_TFloat :: Type
Internal_TDouble :: Type
Internal_TInt8 :: Type
Internal_TInt16 :: Type
Internal_TInt32 :: Type
Internal_TInt64 :: Type
Internal_TWord8 :: Type
Internal_TWord16 :: Type
Internal_TWord32 :: Type
Internal_TWord64 :: Type
Internal_TPtrdiff :: Type
Internal_TSize :: Type
Internal_TSSize :: Type
Internal_TEnum :: CppEnum -> Type
Internal_TBitspace :: Bitspace -> Type
Internal_TPtr :: Type -> Type
Internal_TRef :: Type -> Type
Internal_TFn :: [Type] -> Type -> Type
Internal_TCallback :: Callback -> Type
Internal_TObj :: Class -> Type
Internal_TObjToHeap :: Class -> Type
Internal_TToGc :: Type -> Type
Internal_TConst :: Type -> Type

-- | Canonicalizes a <a>Type</a> without changing its meaning. Multiple
--   nested <a>Internal_TConst</a>s are collapsed into a single one.
normalizeType :: Type -> Type

-- | Strips leading <a>Internal_TConst</a>s off of a type.
stripConst :: Type -> Type

-- | A C++ variable.
data Variable

-- | Creates a binding for a C++ variable.
makeVariable :: Identifier -> Maybe ExtName -> Type -> Variable

-- | The identifier used to refer to the variable.
varIdentifier :: Variable -> Identifier

-- | The variable's external name.
varExtName :: Variable -> ExtName

-- | The variable's type. This may be <a>constT</a> to indicate that the
--   variable is read-only.
varType :: Variable -> Type

-- | Requirements for bindings to use this variable.
varReqs :: Variable -> Reqs

-- | Returns whether the variable is constant, i.e. whether its type is
--   <tt><a>constT</a> ...</tt>.
varIsConst :: Variable -> Bool

-- | Returns the external name of the getter function for the variable.
varGetterExtName :: Variable -> ExtName

-- | Returns the external name of the setter function for the variable.
varSetterExtName :: Variable -> ExtName

-- | A C++ enum declaration. An enum should actually be enumerable (in the
--   sense of Haskell's <a>Enum</a>); if it's not, consider using a
--   <a>Bitspace</a> instead.
data CppEnum

-- | Creates a binding for a C++ enum.
makeEnum :: Identifier -> Maybe ExtName -> [(Int, [String])] -> CppEnum

-- | The identifier used to refer to the enum.
enumIdentifier :: CppEnum -> Identifier

-- | The enum's external name.
enumExtName :: CppEnum -> ExtName

-- | The numeric values and names of the enum values. A single value's name
--   is broken up into words. How the words and ext name get combined to
--   make a name in a particular foreign language depends on the language.
enumValueNames :: CppEnum -> [(Int, [String])]

-- | Requirements for a <a>Type</a> to reference this enum.
enumReqs :: CppEnum -> Reqs

-- | The prefix applied to value names (<a>enumValueNames</a>) when
--   determining the names of values in foreign languages. This defaults to
--   the external name of the enum, plus an underscore.
--   
--   See <a>enumSetValuePrefix</a>.
enumValuePrefix :: CppEnum -> String

-- | Sets the prefix applied to the names of enum values' identifiers in
--   foreign languages.
--   
--   See <a>enumValuePrefix</a>.
enumSetValuePrefix :: String -> CppEnum -> CppEnum

-- | A C++ numeric space with bitwise operations. This is similar to a
--   <a>CppEnum</a>, but in addition to the extra operations, this differs
--   in that these values aren't enumerable.
--   
--   Additionally, as a kludge for Qtah, a bitspace may have a C++ type
--   (<a>bitspaceCppTypeIdentifier</a>) separate from its numeric type
--   (<a>bitspaceType</a>). Qt bitspaces aren't raw numbers but are instead
--   type-safe <tt>QFlags</tt> objects that don't implicitly convert from
--   integers, so we need a means to do so manually. Barring general ad-hoc
--   argument and return value conversion support, we allow this as
--   follows: when given a C++ type, then a bitspace may also have a
--   conversion function between the numeric and C++ type, in each
--   direction. If a conversion function is present, it will be used for
--   conversions in its respective direction. The C++ type is not a full
--   <a>Type</a>, but only an <a>Identifier</a>, since additional
--   information is not needed. See <a>bitspaceAddCppType</a>.
data Bitspace

-- | Creates a binding for a C++ bitspace.
makeBitspace :: ExtName -> Type -> [(Int, [String])] -> Bitspace

-- | The bitspace's external name.
bitspaceExtName :: Bitspace -> ExtName

-- | The C++ type used for bits values. This should be a primitive numeric
--   type, usually <a>intT</a>.
bitspaceType :: Bitspace -> Type

-- | The numeric values and names of the bitspace values. See
--   <a>enumValueNames</a>.
bitspaceValueNames :: Bitspace -> [(Int, [String])]

-- | An associated enum, whose values may be converted to values in the
--   bitspace.
bitspaceEnum :: Bitspace -> Maybe CppEnum

-- | Associates an enum with the bitspace. See <a>bitspaceEnum</a>.
bitspaceAddEnum :: CppEnum -> Bitspace -> Bitspace

-- | The optional C++ type for a bitspace.
bitspaceCppTypeIdentifier :: Bitspace -> Maybe Identifier

-- | The name of a C++ function to convert from the bitspace's C++ type to
--   <a>bitspaceType</a>.
bitspaceFromCppValueFn :: Bitspace -> Maybe String

-- | The name of a C++ function to convert from <a>bitspaceType</a> to the
--   bitspace's C++ type.
bitspaceToCppValueFn :: Bitspace -> Maybe String

-- | <tt>bitspaceAddCppType cppTypeIdentifier toCppValueFn
--   fromCppValueFn</tt> associates a C++ type (plus optional conversion
--   functions) with a bitspace. At least one conversion should be
--   specified, otherwise adding the C++ type will mean nothing. You should
--   also add use requirements to the bitspace for all of these arguments;
--   see <a>HasReqs</a>.
bitspaceAddCppType :: Identifier -> Maybe String -> Maybe String -> Bitspace -> Bitspace

-- | Requirements for emitting the bindings for a bitspace, i.e. what's
--   necessary to reference <a>bitspaceCppTypeIdentifier</a>,
--   <a>bitspaceFromCppValueFn</a>, and <a>bitspaceToCppValueFn</a>.
--   <a>bitspaceType</a> can take some numeric types that require includes
--   as well, but you don't need to list these here.
bitspaceReqs :: Bitspace -> Reqs

-- | The prefix applied to value names (<a>bitspaceValueNames</a>) when
--   determining the names of values in foreign languages. This defaults to
--   the external name of the bitspace, plus an underscore.
--   
--   See <a>bitspaceSetValuePrefix</a>.
bitspaceValuePrefix :: Bitspace -> String

-- | Sets the prefix applied to the names of enum values' identifiers in
--   foreign languages.
--   
--   See <a>enumValuePrefix</a>.
bitspaceSetValuePrefix :: String -> Bitspace -> Bitspace

-- | Whether or not a function may cause side-effects.
--   
--   Haskell bindings for pure functions will not be in <a>IO</a>, and
--   calls to pure functions will be executed non-strictly. Calls to impure
--   functions will execute in the IO monad.
--   
--   Member functions for mutable classes should not be made pure, because
--   it is difficult in general to control when the call will be made.
data Purity

-- | Side-affects are possible.
Nonpure :: Purity

-- | Side-affects will not happen.
Pure :: Purity

-- | A C++ function declaration.
data Function

-- | Creates a binding for a C++ function.
makeFn :: IsFnName Identifier name => name -> Maybe ExtName -> Purity -> [Type] -> Type -> Function

-- | The identifier used to call the function.
fnCName :: Function -> FnName Identifier

-- | The function's external name.
fnExtName :: Function -> ExtName

-- | Whether the function is pure.
fnPurity :: Function -> Purity

-- | The function's parameter types.
fnParams :: Function -> [Type]

-- | The function's return type.
fnReturn :: Function -> Type

-- | Requirements for a binding to call the function.
fnReqs :: Function -> Reqs

-- | Exceptions that the function might throw.
fnExceptionHandlers :: Function -> ExceptionHandlers

-- | A C++ class declaration. See <a>IsClassEntity</a> for more information
--   about the interaction between a class's names and the names of
--   entities within the class.
data Class

-- | Creates a binding for a C++ class and its contents.
makeClass :: Identifier -> Maybe ExtName -> [Class] -> [ClassEntity] -> Class

-- | The identifier used to refer to the class.
classIdentifier :: Class -> Identifier

-- | The class's external name.
classExtName :: Class -> ExtName

-- | The class's public superclasses.
classSuperclasses :: Class -> [Class]

-- | The class's entities.
classEntities :: Class -> [ClassEntity]

-- | Adds constructors to a class.
classAddEntities :: [ClassEntity] -> Class -> Class

-- | Returns all of the class's variables.
classVariables :: Class -> [ClassVariable]

-- | Returns all of the class's constructors.
classCtors :: Class -> [Ctor]

-- | Returns all of the class's methods, including methods generated from
--   <a>Prop</a>s.
classMethods :: Class -> [Method]

-- | The class's methods.
classDtorIsPublic :: Class -> Bool

-- | Marks a class's destructor as private, so that a binding for it won't
--   be generated.
classSetDtorPrivate :: Class -> Class

-- | Behaviour for converting objects to and from foriegn values.
classConversion :: Class -> ClassConversion

-- | Requirements for a <a>Type</a> to reference this class.
classReqs :: Class -> Reqs

-- | The prefix applied to the external names of entities (methods, etc.)
--   within this class when determining the names of foreign languages'
--   corresponding bindings. This defaults to the external name of the
--   class, plus an underscore. Changing this allows you to potentially
--   have entities with the same foreign name in separate modules. This may
--   be the empty string, in which case the foreign name will simply be the
--   external name of the entity.
--   
--   This does <b>not</b> affect the things' external names themselves;
--   external names must still be unique in an interface. For instance, a
--   method with external name <tt>bar</tt> in a class with external name
--   <tt>Flab</tt> and prefix <tt>Flob_</tt> will use the effective
--   external name <tt>Flab_bar</tt>, but the generated name in say Haskell
--   would be <tt>Flob_bar</tt>.
--   
--   See <a>IsClassEntity</a> and <a>classSetEntityPrefix</a>.
classEntityPrefix :: Class -> String

-- | Sets the prefix applied to foreign languages' entities generated from
--   methods, etc. within the class.
--   
--   See <a>IsClassEntity</a> and <a>classEntityPrefix</a>.
classSetEntityPrefix :: String -> Class -> Class

-- | This is true for classes passed through
--   <a>classSetMonomorphicSuperclass</a>.
classIsMonomorphicSuperclass :: Class -> Bool

-- | Explicitly marks a class as being monomorphic (i.e. not having any
--   virtual methods or destructors). By default, Hoppy assumes that a
--   class that is derived is also polymorphic, but it can happen that this
--   is not the case. Downcasting with <tt>dynamic_cast</tt> from such
--   classes is not available. See also
--   <a>classSetSubclassOfMonomorphic</a>.
classSetMonomorphicSuperclass :: Class -> Class

-- | This is true for classes passed through
--   <a>classSetSubclassOfMonomorphic</a>.
classIsSubclassOfMonomorphic :: Class -> Bool

-- | Marks a class as being derived from some monomorphic superclass. This
--   prevents any downcasting to this class. Generally it is better to use
--   <a>classSetMonomorphicSuperclass</a> on the specific superclasses that
--   are monomorphic, but in cases where this is not possible, this
--   function can be applied to the subclass instead.
classSetSubclassOfMonomorphic :: Class -> Class

-- | Whether to support using the class as a C++ exception.
classIsException :: Class -> Bool

-- | Marks a class as being used as an exception. This makes the class
--   throwable and catchable.
classMakeException :: Class -> Class

-- | A C++ entity that belongs to a class.
data ClassEntity
CEVar :: ClassVariable -> ClassEntity
CECtor :: Ctor -> ClassEntity
CEMethod :: Method -> ClassEntity
CEProp :: Prop -> ClassEntity

-- | Things that live inside of a class, and have the class's external name
--   prepended to their own in generated code. With an external name of
--   <tt>"bar"</tt> and a class with external name <tt>"foo"</tt>, the
--   resulting name will be <tt>"foo_bar"</tt>.
--   
--   See <a>classEntityPrefix</a> and <a>classSetEntityPrefix</a>.
class IsClassEntity a

-- | Extracts the external name of the object, without the class name
--   added.
classEntityExtNameSuffix :: IsClassEntity a => a -> ExtName

-- | Computes the external name to use in generated code, containing both
--   the class's and object's external names. This is the concatenation of
--   the class's and entity's external names, separated by an underscore.
classEntityExtName :: IsClassEntity a => Class -> a -> ExtName

-- | Computes the name under which a class entity is to be exposed in
--   foreign languages. This is the concatenation of a class's entity
--   prefix, and the external name of the entity.
classEntityForeignName :: IsClassEntity a => Class -> a -> ExtName

-- | Computes the name under which a class entity is to be exposed in
--   foreign languages, given a class and an entity's external name. The
--   result is the concatenation of a class's entity prefix, and the
--   external name of the entity.
classEntityForeignName' :: Class -> ExtName -> ExtName

-- | A C++ member variable.
data ClassVariable

-- | Creates a <a>ClassVariable</a> with full generality and manual name
--   specification.
--   
--   The result is wrapped in a <a>CEVar</a>. For an unwrapped value, use
--   <a>makeClassVariable_</a>.
makeClassVariable :: String -> Maybe ExtName -> Type -> Staticness -> Bool -> ClassEntity

-- | The unwrapped version of <a>makeClassVariable</a>.
makeClassVariable_ :: String -> Maybe ExtName -> Type -> Staticness -> Bool -> ClassVariable

-- | Creates a <a>ClassVariable</a> for a nonstatic class variable for
--   <tt>class::varName</tt> whose external name is <tt>class_varName</tt>.
--   
--   The result is wrapped in a <a>CEVar</a>. For an unwrapped value, use
--   <a>mkClassVariable_</a>.
mkClassVariable :: String -> Type -> ClassEntity

-- | The unwrapped version of <a>mkClassVariable</a>.
mkClassVariable_ :: String -> Type -> ClassVariable

-- | Same as <a>mkClassVariable</a>, but returns a static variable instead.
--   
--   The result is wrapped in a <a>CEVar</a>. For an unwrapped value, use
--   <a>mkStaticClassVariable_</a>.
mkStaticClassVariable :: String -> Type -> ClassEntity

-- | The unwrapped version of <a>mkStaticClassVariable</a>.
mkStaticClassVariable_ :: String -> Type -> ClassVariable

-- | The variable's C++ name.
classVarCName :: ClassVariable -> String

-- | The variable's external name.
classVarExtName :: ClassVariable -> ExtName

-- | The variable's type. This may be <a>constT</a> to indicate that the
--   variable is read-only.
classVarType :: ClassVariable -> Type

-- | Whether the variable is static (i.e. whether it exists once in the
--   class itself and not in each instance).
classVarStatic :: ClassVariable -> Staticness

-- | Whether the variable should have an accompanying getter. Note this
--   exists only for disabling getters on callback variables - as there is
--   currently no functionality to pass callbacks out of c++
classVarGettable :: ClassVariable -> Bool

-- | Returns the external name of the getter function for the class
--   variable.
classVarGetterExtName :: Class -> ClassVariable -> ExtName

-- | Returns the foreign name of the getter function for the class
--   variable.
classVarGetterForeignName :: Class -> ClassVariable -> ExtName

-- | Returns the external name of the setter function for the class
--   variable.
classVarSetterExtName :: Class -> ClassVariable -> ExtName

-- | Returns the foreign name of the setter function for the class
--   variable.
classVarSetterForeignName :: Class -> ClassVariable -> ExtName

-- | A C++ class constructor declaration.
data Ctor

-- | Creates a <a>Ctor</a> with full generality.
--   
--   The result is wrapped in a <a>CECtor</a>. For an unwrapped value, use
--   <a>makeCtor_</a>.
makeCtor :: ExtName -> [Type] -> ClassEntity

-- | The unwrapped version of <a>makeCtor</a>.
makeCtor_ :: ExtName -> [Type] -> Ctor

-- | <tt>mkCtor name</tt> creates a <a>Ctor</a> whose external name is
--   <tt>className_name</tt>.
--   
--   The result is wrapped in a <a>CECtor</a>. For an unwrapped value, use
--   <a>makeCtor_</a>.
mkCtor :: String -> [Type] -> ClassEntity

-- | The unwrapped version of <a>mkCtor</a>.
mkCtor_ :: String -> [Type] -> Ctor

-- | The constructor's external name.
ctorExtName :: Ctor -> ExtName

-- | The constructor's parameter types.
ctorParams :: Ctor -> [Type]

-- | Exceptions that the constructor may throw.
ctorExceptionHandlers :: Ctor -> ExceptionHandlers

-- | A C++ class method declaration.
--   
--   Any operator function that can be written as a method may have its
--   binding be written either as part of the associated class or as a
--   separate entity, independently of how the function is declared in C++.
data Method

-- | The C++ code to which a <a>Method</a> is bound.
data MethodImpl

-- | The <a>Method</a> is bound to an actual class method.
RealMethod :: (FnName String) -> MethodImpl

-- | The <a>Method</a> is bound to a wrapper function. When wrapping a
--   method with another function, this is preferrable to just using a
--   <a>Function</a> binding because a method will still appear to be part
--   of the class in foreign bindings.
FnMethod :: (FnName Identifier) -> MethodImpl

-- | How a method is associated to its class. A method may be static,
--   const, or neither (a regular method).
data MethodApplicability
MNormal :: MethodApplicability
MStatic :: MethodApplicability
MConst :: MethodApplicability

-- | Whether or not a method is const.
data Constness
Nonconst :: Constness
Const :: Constness

-- | Returns the opposite constness value.
constNegate :: Constness -> Constness

-- | Whether or not a method is static.
data Staticness
Nonstatic :: Staticness
Static :: Staticness

-- | Creates a <a>Method</a> with full generality and manual name
--   specification.
--   
--   The result is wrapped in a <a>CEMethod</a>. For an unwrapped value,
--   use <a>makeMethod_</a>.
makeMethod :: IsFnName String name => name -> ExtName -> MethodApplicability -> Purity -> [Type] -> Type -> ClassEntity

-- | The unwrapped version of <a>makeMethod</a>.
makeMethod_ :: IsFnName String name => name -> ExtName -> MethodApplicability -> Purity -> [Type] -> Type -> Method

-- | Creates a <a>Method</a> that is in fact backed by a C++ non-member
--   function (a la <a>makeFn</a>), but appears to be a regular method.
--   This is useful for wrapping a method on the C++ side when its
--   arguments aren't right for binding directly.
--   
--   A <tt>this</tt> pointer parameter is <b>not</b> automatically added to
--   the parameter list for non-static methods created with
--   <tt>makeFnMethod</tt>.
--   
--   The result is wrapped in a <a>CEMethod</a>. For an unwrapped value,
--   use <a>makeFnMethod_</a>.
makeFnMethod :: IsFnName Identifier name => name -> String -> MethodApplicability -> Purity -> [Type] -> Type -> ClassEntity

-- | The unwrapped version of <a>makeFnMethod</a>.
makeFnMethod_ :: IsFnName Identifier name => name -> String -> MethodApplicability -> Purity -> [Type] -> Type -> Method

-- | Creates a nonconst, nonstatic <a>Method</a> for
--   <tt>class::methodName</tt> and whose external name is
--   <tt>class_methodName</tt>. If the name is an operator, then the
--   <a>operatorPreferredExtName</a> will be used in the external name.
--   
--   For creating multiple bindings to a method, see <a>mkMethod'</a>.
--   
--   The result is wrapped in a <a>CEMethod</a>. For an unwrapped value,
--   use <a>mkMethod_</a>.
mkMethod :: IsFnName String name => name -> [Type] -> Type -> ClassEntity

-- | The unwrapped version of <a>mkMethod</a>.
mkMethod_ :: IsFnName String name => name -> [Type] -> Type -> Method

-- | Creates a nonconst, nonstatic <a>Method</a> for method
--   <tt>class::methodName</tt> and whose external name is
--   <tt>class_methodName</tt>. This enables multiple <a>Method</a>s with
--   different foreign names (and hence different external names) to bind
--   to the same method, e.g. to make use of optional arguments or
--   overloading. See <a>mkMethod</a> for a simpler form.
--   
--   The result is wrapped in a <a>CEMethod</a>. For an unwrapped value,
--   use <a>mkMethod'_</a>.
mkMethod' :: IsFnName String name => name -> String -> [Type] -> Type -> ClassEntity

-- | The unwrapped version of <a>mkMethod'</a>.
mkMethod'_ :: IsFnName String name => name -> String -> [Type] -> Type -> Method

-- | Same as <a>mkMethod</a>, but returns an <a>MConst</a> method.
--   
--   The result is wrapped in a <a>CEMethod</a>. For an unwrapped value,
--   use <a>mkConstMethod_</a>.
mkConstMethod :: IsFnName String name => name -> [Type] -> Type -> ClassEntity

-- | The unwrapped version of <a>mkConstMethod</a>.
mkConstMethod_ :: IsFnName String name => name -> [Type] -> Type -> Method

-- | Same as <a>mkMethod'</a>, but returns an <a>MConst</a> method.
--   
--   The result is wrapped in a <a>CEMethod</a>. For an unwrapped value,
--   use <a>mkConstMethod'_</a>.
mkConstMethod' :: IsFnName String name => name -> String -> [Type] -> Type -> ClassEntity

-- | The unwrapped version of <a>mkConstMethod'</a>.
mkConstMethod'_ :: IsFnName String name => name -> String -> [Type] -> Type -> Method

-- | Same as <a>mkMethod</a>, but returns an <a>MStatic</a> method.
--   
--   The result is wrapped in a <a>CEMethod</a>. For an unwrapped value,
--   use <a>mkStaticMethod_</a>.
mkStaticMethod :: IsFnName String name => name -> [Type] -> Type -> ClassEntity

-- | The unwrapped version of <a>mkStaticMethod</a>.
mkStaticMethod_ :: IsFnName String name => name -> [Type] -> Type -> Method

-- | Same as <a>mkMethod'</a>, but returns an <a>MStatic</a> method.
--   
--   The result is wrapped in a <a>CEMethod</a>. For an unwrapped value,
--   use <a>mkStaticMethod'_</a>.
mkStaticMethod' :: IsFnName String name => name -> String -> [Type] -> Type -> ClassEntity

-- | The unwrapped version of <a>mkStaticMethod'</a>.
mkStaticMethod'_ :: IsFnName String name => name -> String -> [Type] -> Type -> Method

-- | A "property" getter/setter pair.
data Prop

-- | Creates a getter/setter binding pair for methods:
--   
--   <pre>
--   T foo() const
--   void setFoo(T)
--   </pre>
--   
--   The result is wrapped in a <a>CEProp</a>. For an unwrapped value, use
--   <a>mkProp_</a>.
mkProp :: String -> Type -> ClassEntity

-- | The unwrapped version of <a>mkProp</a>.
mkProp_ :: String -> Type -> Prop

-- | Creates a getter/setter binding pair for static methods:
--   
--   <pre>
--   static T foo() const
--   static void setFoo(T)
--   </pre>
mkStaticProp :: String -> Type -> ClassEntity

-- | The unwrapped version of <a>mkStaticProp</a>.
mkStaticProp_ :: String -> Type -> Prop

-- | Creates a getter/setter binding pair for boolean methods, where the
--   getter is prefixed with <tt>is</tt>:
--   
--   <pre>
--   bool isFoo() const
--   void setFoo(bool)
--   </pre>
--   
--   The result is wrapped in a <a>CEProp</a>. For an unwrapped value, use
--   <a>mkBoolIsProp_</a>.
mkBoolIsProp :: String -> ClassEntity

-- | The unwrapped version of <a>mkBoolIsProp</a>.
mkBoolIsProp_ :: String -> Prop

-- | Creates a getter/setter binding pair for boolean methods, where the
--   getter is prefixed with <tt>has</tt>:
--   
--   <pre>
--   bool hasFoo() const
--   void setFoo(bool)
--   </pre>
--   
--   The result is wrapped in a <a>CEProp</a>. For an unwrapped value, use
--   <a>mkBoolHasProp_</a>.
mkBoolHasProp :: String -> ClassEntity

-- | The unwrapped version of <a>mkBoolHasProp</a>.
mkBoolHasProp_ :: String -> Prop

-- | The underlying code that the binding calls.
methodImpl :: Method -> MethodImpl

-- | The method's external name.
methodExtName :: Method -> ExtName

-- | How the method is associated to its class.
methodApplicability :: Method -> MethodApplicability

-- | Whether the method is pure.
methodPurity :: Method -> Purity

-- | The method's parameter types.
methodParams :: Method -> [Type]

-- | The method's return type.
methodReturn :: Method -> Type

-- | Exceptions that the method might throw.
methodExceptionHandlers :: Method -> ExceptionHandlers

-- | Returns the constness of a method, based on its
--   <a>methodApplicability</a>.
methodConst :: Method -> Constness

-- | Returns the staticness of a method, based on its
--   <a>methodApplicability</a>.
methodStatic :: Method -> Staticness

-- | Separately from passing object handles between C++ and foreign
--   languages, objects can also be made to implicitly convert to native
--   values in foreign languages. A single such type may be associated with
--   any C++ class for each foreign language. The foreign type and the
--   conversion process in each direction are specified using this object.
--   Converting a C++ object to a foreign value is also called decoding,
--   and vice versa is called encoding. A class may be convertible in one
--   direction and not the other.
--   
--   To use these implicit conversions, instead of specifying an object
--   handle type such as <tt><a>ptrT</a> . <a>objT</a></tt> or
--   <tt><a>refT</a> . <a>objT</a></tt>, use <a>objT</a> directly.
--   
--   The subfields in this object specify how to do conversions between C++
--   and foreign languages.
data ClassConversion
ClassConversion :: ClassHaskellConversion -> ClassConversion

-- | Conversions to and from Haskell.
[classHaskellConversion] :: ClassConversion -> ClassHaskellConversion

-- | Conversion behaviour for a class that is not convertible.
classConversionNone :: ClassConversion

-- | Modifies a class's <a>ClassConversion</a> structure with a given
--   function.
classModifyConversion :: (ClassConversion -> ClassConversion) -> Class -> Class

-- | Replaces a class's <a>ClassConversion</a> structure.
classSetConversion :: ClassConversion -> Class -> Class

-- | Controls how conversions between C++ objects and Haskell values happen
--   in Haskell bindings.
data ClassHaskellConversion
ClassHaskellConversion :: Maybe (Generator HsType) -> Maybe (Generator ()) -> Maybe (Generator ()) -> ClassHaskellConversion

-- | Produces the Haskell type that represents a value of the corresponding
--   C++ class. This generator may add imports, but must not output code or
--   add exports.
[classHaskellConversionType] :: ClassHaskellConversion -> Maybe (Generator HsType)

-- | Produces a Haskell expression that evaluates to a function that takes
--   an value of the type that <a>classHaskellConversionType</a> generates,
--   and returns a non-const handle for a new C++ object in IO. The
--   generator must output code and may add imports, but must not add
--   exports.
--   
--   If this field is present, then <a>classHaskellConversionType</a> must
--   also be present.
[classHaskellConversionToCppFn] :: ClassHaskellConversion -> Maybe (Generator ())

-- | Produces a Haskell expression that evaluates to a function that takes
--   a const handle for a C++ object, and returns a value of the type that
--   <a>classHaskellConversionType</a> generates, in IO. It should not
--   delete the handle. The generator must output code and may add imports,
--   but must not add exports.
--   
--   If this field is present, then <a>classHaskellConversionType</a> must
--   also be present.
[classHaskellConversionFromCppFn] :: ClassHaskellConversion -> Maybe (Generator ())

-- | Conversion behaviour for a class that is not convertible to or from
--   Haskell.
classHaskellConversionNone :: ClassHaskellConversion

-- | Replaces a class's <a>classHaskellConversion</a> with a given value.
classSetHaskellConversion :: ClassHaskellConversion -> Class -> Class

-- | A non-C++ function that can be invoked via a C++ functor or function
--   pointer.
data Callback

-- | Creates a binding for constructing callbacks into foreign code.
makeCallback :: ExtName -> [Type] -> Type -> Callback

-- | The callback's external name.
callbackExtName :: Callback -> ExtName

-- | The callback's parameter types.
callbackParams :: Callback -> [Type]

-- | The callback's return type.
callbackReturn :: Callback -> Type

-- | Whether the callback supports throwing C++ exceptions from Haskell
--   into C++ during its execution. When absent, the value is inherited
--   from <a>moduleCallbacksThrow</a> and <a>interfaceCallbacksThrow</a>.
callbackThrows :: Callback -> Maybe Bool

-- | Requirements for the callback.
callbackReqs :: Callback -> Reqs

-- | Sets whether a callback supports handling thrown C++ exceptions and
--   passing them into C++.
callbackSetThrows :: Bool -> Callback -> Callback

-- | Each exception class has a unique exception ID.
newtype ExceptionId
ExceptionId :: Int -> ExceptionId

-- | Internal.
[getExceptionId] :: ExceptionId -> Int

-- | The exception ID that represents the catch-all type.
exceptionCatchAllId :: ExceptionId

-- | Indicates the ability to handle a certain type of C++ exception.
data ExceptionHandler

-- | Indicates that instances of the given class are handled (including
--   derived types).
CatchClass :: Class -> ExceptionHandler

-- | Indicates that all C++ exceptions are handled, i.e. <tt>catch
--   (...)</tt>.
CatchAll :: ExceptionHandler

-- | Represents a list of exception handlers to be used for a body of code.
--   Order is important; a <a>CatchAll</a> will prevent all subsequent
--   handlers from being invoked.
data ExceptionHandlers
ExceptionHandlers :: [ExceptionHandler] -> ExceptionHandlers

-- | Extracts the list of exception handlers.
[exceptionHandlersList] :: ExceptionHandlers -> [ExceptionHandler]

-- | Types that can handle exceptions.
class HandlesExceptions a

-- | Extracts the exception handlers for an object.
getExceptionHandlers :: HandlesExceptions a => a -> ExceptionHandlers

-- | Appends additional exception handlers to an object.
handleExceptions :: HandlesExceptions a => [ExceptionHandler] -> a -> a

-- | A literal piece of code that will be inserted into a generated source
--   file after the regular binding glue. The <a>Monoid</a> instance
--   concatenates code (actions).
data Addendum
Addendum :: Generator () -> Addendum

-- | Code to be output into the Haskell binding. May also add imports and
--   exports.
[addendumHaskell] :: Addendum -> Generator ()

-- | A typeclass for types that have an addendum.
class HasAddendum a where setAddendum addendum = modifyAddendum $ const addendum modifyAddendum f x = setAddendum (f $ getAddendum x) x

-- | Returns an object's addendum.
getAddendum :: HasAddendum a => a -> Addendum

-- | Replaces and object's addendum with another.
setAddendum :: HasAddendum a => Addendum -> a -> a

-- | Modified an object's addendum.
modifyAddendum :: HasAddendum a => (Addendum -> Addendum) -> a -> a

-- | Adds a Haskell addendum to an object.
addAddendumHaskell :: HasAddendum a => Generator () -> a -> a

-- | A Haskell module name.
type HsModuleName = String

-- | A collection of imports for a Haskell module. This is a monoid: import
--   Statements are merged to give the union of imported bindings.
--   
--   This structure supports two specific types of imports: - <tt>import
--   Foo (...)</tt> - <tt>import qualified Foo as Bar</tt> Imports with
--   <tt>as</tt> but without <tt>qualified</tt>, and <tt>qualified</tt>
--   imports with a spec list, are not supported. This satisfies the needs
--   of the code generator, and keeps the merging logic simple.
data HsImportSet

-- | References an occurrence of an import statement, under which bindings
--   can be imported. Only imported specs under equal <a>HsImportKey</a>s
--   may be merged.
data HsImportKey
HsImportKey :: HsModuleName -> Maybe HsModuleName -> HsImportKey
[hsImportModule] :: HsImportKey -> HsModuleName
[hsImportQualifiedName] :: HsImportKey -> Maybe HsModuleName

-- | A specification of bindings to import from a module. If
--   <a>Nothing</a>, then the entire module is imported. If <tt><a>Just</a>
--   <a>empty</a></tt>, then only instances are imported.
data HsImportSpecs
HsImportSpecs :: Maybe (Map HsImportName HsImportVal) -> Bool -> HsImportSpecs
[getHsImportSpecs] :: HsImportSpecs -> Maybe (Map HsImportName HsImportVal)
[hsImportSource] :: HsImportSpecs -> Bool

-- | An identifier that can be imported from a module. Symbols may be used
--   here when surrounded by parentheses. Examples are <tt>"fmap"</tt> and
--   <tt>"(++)"</tt>.
type HsImportName = String

-- | Specifies how a name is imported.
data HsImportVal

-- | The name is imported, and nothing underneath it is.
HsImportVal :: HsImportVal

-- | The name is imported, as are specific names underneath it. This is a
--   <tt>X (a, b, c)</tt> import.
HsImportValSome :: [HsImportName] -> HsImportVal

-- | The name is imported, along with all names underneath it. This is a
--   <tt>X (..)</tt> import.
HsImportValAll :: HsImportVal

-- | An import for the entire contents of a Haskell module.
hsWholeModuleImport :: HsModuleName -> HsImportSet

-- | A qualified import of a Haskell module.
hsQualifiedImport :: HsModuleName -> HsModuleName -> HsImportSet

-- | An import of a single name from a Haskell module.
hsImport1 :: HsModuleName -> HsImportName -> HsImportSet

-- | A detailed import of a single name from a Haskell module.
hsImport1' :: HsModuleName -> HsImportName -> HsImportVal -> HsImportSet

-- | An import of multiple names from a Haskell module.
hsImports :: HsModuleName -> [HsImportName] -> HsImportSet

-- | A detailed import of multiple names from a Haskell module.
hsImports' :: HsModuleName -> [(HsImportName, HsImportVal)] -> HsImportSet

-- | Sets all of the import specifications in an import set to be
--   <tt>{--}</tt> imports.
hsImportSetMakeSource :: HsImportSet -> HsImportSet

-- | Returns all of the exception classes in an interface.
interfaceAllExceptionClasses :: Interface -> [Class]

-- | Searches a class for a copy constructor, returning it if found.
classFindCopyCtor :: Class -> Maybe Ctor

-- | Constructor for an import set.
makeHsImportSet :: Map HsImportKey HsImportSpecs -> HsImportSet

-- | Returns the import set's internal map from module names to imported
--   bindings.
getHsImportSet :: HsImportSet -> Map HsImportKey HsImportSpecs

-- | Imports <a>Data.Bits</a> qualified as <tt>HoppyDB</tt>.
hsImportForBits :: HsImportSet

-- | Imports <a>Control.Exception</a> qualified as <tt>HoppyCE</tt>.
hsImportForException :: HsImportSet

-- | Imports <a>Data.Int</a> qualified as <tt>HoppyDI</tt>.
hsImportForInt :: HsImportSet

-- | Imports <a>Data.Word</a> qualified as <tt>HoppyDW</tt>.
hsImportForWord :: HsImportSet

-- | Imports <a>Foreign</a> qualified as <tt>HoppyF</tt>.
hsImportForForeign :: HsImportSet

-- | Imports <a>Foreign.C</a> qualified as <tt>HoppyFC</tt>.
hsImportForForeignC :: HsImportSet

-- | Imports <a>Data.Map</a> qualified as <tt>HoppyDM</tt>.
hsImportForMap :: HsImportSet

-- | Imports <a>Prelude</a> qualified as <tt>HoppyP</tt>.
hsImportForPrelude :: HsImportSet

-- | Imports <a>Foreign.Hoppy.Runtime</a> qualified as <tt>HoppyFHR</tt>.
hsImportForRuntime :: HsImportSet

-- | Imports <a>System.Posix.Types</a> qualified as <tt>HoppySPT</tt>.
hsImportForSystemPosixTypes :: HsImportSet

-- | Imports <a>Data.Typeable</a> qualified as <tt>HoppyDT</tt>.
hsImportForTypeable :: HsImportSet

-- | Imports <a>System.IO.Unsafe</a> qualified as <tt>HoppySIU</tt>.
hsImportForUnsafeIO :: HsImportSet

-- | Returns an error message indicating that <a>objToHeapT</a> is used
--   where data is going from a foreign language into C++.
objToHeapTWrongDirectionErrorMsg :: Maybe String -> Class -> String

-- | Returns an error message indicating that <a>objToHeapT</a> is used
--   where data is going from a foreign language into C++.
tToGcInvalidFormErrorMessage :: Maybe String -> Type -> String

-- | Returns an error message indicating that <a>toGcT</a> is used where
--   data is going from a foreign language into C++.
toGcTWrongDirectionErrorMsg :: Maybe String -> Type -> String

-- | Modifies a class's <a>ClassConversion</a> structure by setting all
--   languages to use <tt>ClassConversionToHeap</tt>.
classSetConversionToHeap :: Class -> Class

-- | Modifies a class's <a>ClassConversion</a> structure by setting all
--   languages that support garbage collection to use
--   <tt>ClassConversionToGc</tt>.
classSetConversionToGc :: Class -> Class


-- | Shared portion of the C++ code generator. Usable by binding
--   definitions.
module Foreign.Hoppy.Generator.Language.Cpp

-- | Returns the C++ binding function name for an external name.
externalNameToCpp :: ExtName -> String

-- | Returns the C++ binding function name of the wrapper for the delete
--   method for a class.
classDeleteFnCppName :: Class -> String

-- | <tt>classCastFnCppName fromCls toCls</tt> returns the name of the
--   generated C++ function that casts a pointer from <tt>fromCls</tt> to
--   <tt>toCls</tt>.
classCastFnCppName :: Class -> Class -> String

-- | Returns the name of the outer, copyable class for a callback.
callbackClassName :: Callback -> String

-- | Returns the name of the internal, non-copyable implementation class
--   for a callback.
callbackImplClassName :: Callback -> String

-- | Returns the name of the C++ binding function that creates a C++
--   callback wrapper object from a function pointer to foreign code.
callbackFnName :: Callback -> String

-- | Returns a distinct argument variable name for each nonnegative number.
toArgName :: Int -> String

-- | Same as <a>toArgName</a>, but with distinct names, with with
--   similarity between <tt>toArgName n</tt> and <tt>toArgNameAlt n</tt>.
toArgNameAlt :: Int -> String

-- | The C++ variable name to use for the exception ID argument in a
--   gateway function.
exceptionIdArgName :: String

-- | The C++ variable name to use for the exception pointer argument in a
--   gateway function.
exceptionPtrArgName :: String

-- | The C++ variable name to use in a <tt>catch</tt> statement in a
--   gateway function.
exceptionVarName :: String

-- | The name of the C++ function that receives an exception from a foreign
--   language and throws it in C++.
exceptionRethrowFnName :: String

-- | A chunk is a string that contains an arbitrary portion of C++ code.
--   The only requirement is that chunk boundaries are also C++ token
--   boundaries, because the generator monad automates the process of
--   inserting whitespace between chunk boundaries where necessary.
newtype Chunk
Chunk :: String -> Chunk
[chunkContents] :: Chunk -> String

-- | Runs a <a>Chunk</a> writer, combining them with <a>combineChunks</a>
--   to form a single string.
runChunkWriter :: Writer [Chunk] a -> (a, String)

-- | Runs a <a>Chunk</a> writer and returns the monad's value.
evalChunkWriter :: Writer [Chunk] a -> a

-- | Runs a <a>Chunk</a> writer and returns the written log.
execChunkWriter :: Writer [Chunk] a -> String

-- | Runs a <a>Chunk</a> writer transformer, combining them with
--   <a>combineChunks</a> to form a single string.
runChunkWriterT :: Monad m => WriterT [Chunk] m a -> m (a, String)

-- | Runs a <a>Chunk</a> writer transformer and returns the monad's value.
evalChunkWriterT :: Monad m => WriterT [Chunk] m a -> m a

-- | Runs a <a>Chunk</a> writer transformer and returns the written log.
execChunkWriterT :: Monad m => WriterT [Chunk] m a -> m String

-- | Emits a single <a>Chunk</a>.
say :: MonadWriter [Chunk] m => String -> m ()

-- | Emits a <a>Chunk</a> for each string in a list.
says :: MonadWriter [Chunk] m => [String] -> m ()

-- | Emits an <a>Identifier</a>.
sayIdentifier :: MonadWriter [Chunk] m => Identifier -> m ()

-- | <tt>sayVar name maybeParamNames t</tt> speaks a variable declaration
--   of the form <tt>&lt;type&gt; &lt;name&gt;</tt>, where
--   <tt>&lt;name&gt;</tt> is the given name, and <tt>&lt;type&gt;</tt> is
--   rendered by giving <tt>maybeParamNames</tt> and <tt>t</tt> to
--   <a>sayType</a>.
--   
--   This function is useful for generating variable declarations,
--   declarations with assignments, and function prototypes and
--   definitions.
sayVar :: MonadWriter [Chunk] m => String -> Maybe [String] -> Type -> m ()

-- | <tt>sayType maybeParamNames t</tt> renders <tt>t</tt> in C++ syntax.
--   If <tt>t</tt> is a <a>fnT</a>, then <tt>maybeParamNames</tt> will
--   provide variable names for parameters, if present.
sayType :: MonadWriter [Chunk] m => Maybe [String] -> Type -> m ()


-- | A driver for a command-line interface to a generator.
--   
--   A simple <tt>Main.hs</tt> for a generator can simply be:
--   
--   <pre>
--   import <a>Foreign.Hoppy.Generator.Main</a> (<a>defaultMain</a>)
--   import <a>Foreign.Hoppy.Generator.Spec</a> (<a>ErrorMsg</a>, <a>Interface</a>, <a>interface</a>)
--   
--   interfaceResult :: Either <a>ErrorMsg</a> <a>Interface</a>
--   interfaceResult = <a>interface</a> ...
--   
--   main :: IO ()
--   main = <a>defaultMain</a> interfaceResult
--   </pre>
module Foreign.Hoppy.Generator.Main

-- | Actions that can be requested of the program.
data Action

-- | Lists the interfaces compiled into the generator.
ListInterfaces :: Action

-- | Lists the generated files in C++ bindings.
ListCppFiles :: Action

-- | Lists the generated files in Haskell bindings.
ListHsFiles :: Action

-- | Generates C++ wrappers for an interface in the given location.
GenCpp :: FilePath -> Action

-- | Generates Haskell bindings for an interface in the given location.
GenHaskell :: FilePath -> Action

-- | This provides a simple <tt>main</tt> function for a generator. Define
--   your <tt>main</tt> as:
--   
--   <pre>
--   main = defaultMain $ <a>interface</a> ...
--   </pre>
--   
--   Refer to <a>run</a> for how to use the command-line interface.
defaultMain :: Either String Interface -> IO ()

-- | <tt>run interfaces args</tt> runs the driver with the command-line
--   arguments from <tt>args</tt> against the listed interfaces, and
--   returns the list of actions performed.
--   
--   The recognized arguments are listed below. The exact forms shown are
--   required; the <tt>--long-arg=value</tt> style is not supported.
--   
--   <ul>
--   <li><b><tt>--help</tt>:</b> Displays a menu listing the valid
--   commands.</li>
--   <li><b><tt>--list-interfaces</tt>:</b> Lists the interfaces compiled
--   into the generator.</li>
--   <li><b><tt>--gen-cpp &lt;outdir&gt;</tt>:</b> Generates C++ bindings
--   in the given directory.</li>
--   <li><b><tt>--gen-hs &lt;outdir&gt;</tt>:</b> Generates Haskell
--   bindings under the given top-level source directory.</li>
--   </ul>
run :: [Interface] -> [String] -> IO [Action]
