trunk/3rdparty/luabridge/Doxyfile
| r0 | r242832 | |
| 1 | # Doxyfile 1.8.1.1 |
| 2 | |
| 3 | # This file describes the settings to be used by the documentation system |
| 4 | # doxygen (www.doxygen.org) for a project. |
| 5 | # |
| 6 | # All text after a hash (#) is considered a comment and will be ignored. |
| 7 | # The format is: |
| 8 | # TAG = value [value, ...] |
| 9 | # For lists items can also be appended using: |
| 10 | # TAG += value [value, ...] |
| 11 | # Values that contain spaces should be placed between quotes (" "). |
| 12 | |
| 13 | #--------------------------------------------------------------------------- |
| 14 | # Project related configuration options |
| 15 | #--------------------------------------------------------------------------- |
| 16 | |
| 17 | # This tag specifies the encoding used for all characters in the config file |
| 18 | # that follow. The default is UTF-8 which is also the encoding used for all |
| 19 | # text before the first occurrence of this tag. Doxygen uses libiconv (or the |
| 20 | # iconv built into libc) for the transcoding. See |
| 21 | # http://www.gnu.org/software/libiconv for the list of possible encodings. |
| 22 | |
| 23 | DOXYFILE_ENCODING = UTF-8 |
| 24 | |
| 25 | # The PROJECT_NAME tag is a single word (or sequence of words) that should |
| 26 | # identify the project. Note that if you do not use Doxywizard you need |
| 27 | # to put quotes around the project name if it contains spaces. |
| 28 | |
| 29 | PROJECT_NAME = LuaBridge |
| 30 | |
| 31 | # The PROJECT_NUMBER tag can be used to enter a project or revision number. |
| 32 | # This could be handy for archiving the generated documentation or |
| 33 | # if some version control system is used. |
| 34 | |
| 35 | PROJECT_NUMBER = |
| 36 | |
| 37 | # Using the PROJECT_BRIEF tag one can provide an optional one line description |
| 38 | # for a project that appears at the top of each page and should give viewer |
| 39 | # a quick idea about the purpose of the project. Keep the description short. |
| 40 | |
| 41 | PROJECT_BRIEF = |
| 42 | |
| 43 | # With the PROJECT_LOGO tag one can specify an logo or icon that is |
| 44 | # included in the documentation. The maximum height of the logo should not |
| 45 | # exceed 55 pixels and the maximum width should not exceed 200 pixels. |
| 46 | # Doxygen will copy the logo to the output directory. |
| 47 | |
| 48 | PROJECT_LOGO = |
| 49 | |
| 50 | # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) |
| 51 | # base path where the generated documentation will be put. |
| 52 | # If a relative path is entered, it will be relative to the location |
| 53 | # where doxygen was started. If left blank the current directory will be used. |
| 54 | |
| 55 | OUTPUT_DIRECTORY = |
| 56 | |
| 57 | # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create |
| 58 | # 4096 sub-directories (in 2 levels) under the output directory of each output |
| 59 | # format and will distribute the generated files over these directories. |
| 60 | # Enabling this option can be useful when feeding doxygen a huge amount of |
| 61 | # source files, where putting all generated files in the same directory would |
| 62 | # otherwise cause performance problems for the file system. |
| 63 | |
| 64 | CREATE_SUBDIRS = NO |
| 65 | |
| 66 | # The OUTPUT_LANGUAGE tag is used to specify the language in which all |
| 67 | # documentation generated by doxygen is written. Doxygen will use this |
| 68 | # information to generate all constant output in the proper language. |
| 69 | # The default language is English, other supported languages are: |
| 70 | # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, |
| 71 | # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, |
| 72 | # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English |
| 73 | # messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, |
| 74 | # Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, |
| 75 | # Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. |
| 76 | |
| 77 | OUTPUT_LANGUAGE = English |
| 78 | |
| 79 | # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will |
| 80 | # include brief member descriptions after the members that are listed in |
| 81 | # the file and class documentation (similar to JavaDoc). |
| 82 | # Set to NO to disable this. |
| 83 | |
| 84 | BRIEF_MEMBER_DESC = YES |
| 85 | |
| 86 | # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend |
| 87 | # the brief description of a member or function before the detailed description. |
| 88 | # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the |
| 89 | # brief descriptions will be completely suppressed. |
| 90 | |
| 91 | REPEAT_BRIEF = NO |
| 92 | |
| 93 | # This tag implements a quasi-intelligent brief description abbreviator |
| 94 | # that is used to form the text in various listings. Each string |
| 95 | # in this list, if found as the leading text of the brief description, will be |
| 96 | # stripped from the text and the result after processing the whole list, is |
| 97 | # used as the annotated text. Otherwise, the brief description is used as-is. |
| 98 | # If left blank, the following values are used ("$name" is automatically |
| 99 | # replaced with the name of the entity): "The $name class" "The $name widget" |
| 100 | # "The $name file" "is" "provides" "specifies" "contains" |
| 101 | # "represents" "a" "an" "the" |
| 102 | |
| 103 | ABBREVIATE_BRIEF = |
| 104 | |
| 105 | # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then |
| 106 | # Doxygen will generate a detailed section even if there is only a brief |
| 107 | # description. |
| 108 | |
| 109 | ALWAYS_DETAILED_SEC = NO |
| 110 | |
| 111 | # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all |
| 112 | # inherited members of a class in the documentation of that class as if those |
| 113 | # members were ordinary class members. Constructors, destructors and assignment |
| 114 | # operators of the base classes will not be shown. |
| 115 | |
| 116 | INLINE_INHERITED_MEMB = NO |
| 117 | |
| 118 | # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full |
| 119 | # path before files name in the file list and in the header files. If set |
| 120 | # to NO the shortest path that makes the file name unique will be used. |
| 121 | |
| 122 | FULL_PATH_NAMES = NO |
| 123 | |
| 124 | # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag |
| 125 | # can be used to strip a user-defined part of the path. Stripping is |
| 126 | # only done if one of the specified strings matches the left-hand part of |
| 127 | # the path. The tag can be used to show relative paths in the file list. |
| 128 | # If left blank the directory from which doxygen is run is used as the |
| 129 | # path to strip. |
| 130 | |
| 131 | STRIP_FROM_PATH = |
| 132 | |
| 133 | # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of |
| 134 | # the path mentioned in the documentation of a class, which tells |
| 135 | # the reader which header file to include in order to use a class. |
| 136 | # If left blank only the name of the header file containing the class |
| 137 | # definition is used. Otherwise one should specify the include paths that |
| 138 | # are normally passed to the compiler using the -I flag. |
| 139 | |
| 140 | STRIP_FROM_INC_PATH = |
| 141 | |
| 142 | # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter |
| 143 | # (but less readable) file names. This can be useful if your file system |
| 144 | # doesn't support long names like on DOS, Mac, or CD-ROM. |
| 145 | |
| 146 | SHORT_NAMES = NO |
| 147 | |
| 148 | # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen |
| 149 | # will interpret the first line (until the first dot) of a JavaDoc-style |
| 150 | # comment as the brief description. If set to NO, the JavaDoc |
| 151 | # comments will behave just like regular Qt-style comments |
| 152 | # (thus requiring an explicit @brief command for a brief description.) |
| 153 | |
| 154 | JAVADOC_AUTOBRIEF = YES |
| 155 | |
| 156 | # If the QT_AUTOBRIEF tag is set to YES then Doxygen will |
| 157 | # interpret the first line (until the first dot) of a Qt-style |
| 158 | # comment as the brief description. If set to NO, the comments |
| 159 | # will behave just like regular Qt-style comments (thus requiring |
| 160 | # an explicit \brief command for a brief description.) |
| 161 | |
| 162 | QT_AUTOBRIEF = NO |
| 163 | |
| 164 | # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen |
| 165 | # treat a multi-line C++ special comment block (i.e. a block of //! or /// |
| 166 | # comments) as a brief description. This used to be the default behaviour. |
| 167 | # The new default is to treat a multi-line C++ comment block as a detailed |
| 168 | # description. Set this tag to YES if you prefer the old behaviour instead. |
| 169 | |
| 170 | MULTILINE_CPP_IS_BRIEF = NO |
| 171 | |
| 172 | # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented |
| 173 | # member inherits the documentation from any documented member that it |
| 174 | # re-implements. |
| 175 | |
| 176 | INHERIT_DOCS = YES |
| 177 | |
| 178 | # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce |
| 179 | # a new page for each member. If set to NO, the documentation of a member will |
| 180 | # be part of the file/class/namespace that contains it. |
| 181 | |
| 182 | SEPARATE_MEMBER_PAGES = NO |
| 183 | |
| 184 | # The TAB_SIZE tag can be used to set the number of spaces in a tab. |
| 185 | # Doxygen uses this value to replace tabs by spaces in code fragments. |
| 186 | |
| 187 | TAB_SIZE = 4 |
| 188 | |
| 189 | # This tag can be used to specify a number of aliases that acts |
| 190 | # as commands in the documentation. An alias has the form "name=value". |
| 191 | # For example adding "sideeffect=\par Side Effects:\n" will allow you to |
| 192 | # put the command \sideeffect (or @sideeffect) in the documentation, which |
| 193 | # will result in a user-defined paragraph with heading "Side Effects:". |
| 194 | # You can put \n's in the value part of an alias to insert newlines. |
| 195 | |
| 196 | ALIASES = |
| 197 | |
| 198 | # This tag can be used to specify a number of word-keyword mappings (TCL only). |
| 199 | # A mapping has the form "name=value". For example adding |
| 200 | # "class=itcl::class" will allow you to use the command class in the |
| 201 | # itcl::class meaning. |
| 202 | |
| 203 | TCL_SUBST = |
| 204 | |
| 205 | # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C |
| 206 | # sources only. Doxygen will then generate output that is more tailored for C. |
| 207 | # For instance, some of the names that are used will be different. The list |
| 208 | # of all members will be omitted, etc. |
| 209 | |
| 210 | OPTIMIZE_OUTPUT_FOR_C = NO |
| 211 | |
| 212 | # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java |
| 213 | # sources only. Doxygen will then generate output that is more tailored for |
| 214 | # Java. For instance, namespaces will be presented as packages, qualified |
| 215 | # scopes will look different, etc. |
| 216 | |
| 217 | OPTIMIZE_OUTPUT_JAVA = NO |
| 218 | |
| 219 | # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran |
| 220 | # sources only. Doxygen will then generate output that is more tailored for |
| 221 | # Fortran. |
| 222 | |
| 223 | OPTIMIZE_FOR_FORTRAN = NO |
| 224 | |
| 225 | # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL |
| 226 | # sources. Doxygen will then generate output that is tailored for |
| 227 | # VHDL. |
| 228 | |
| 229 | OPTIMIZE_OUTPUT_VHDL = NO |
| 230 | |
| 231 | # Doxygen selects the parser to use depending on the extension of the files it |
| 232 | # parses. With this tag you can assign which parser to use for a given extension. |
| 233 | # Doxygen has a built-in mapping, but you can override or extend it using this |
| 234 | # tag. The format is ext=language, where ext is a file extension, and language |
| 235 | # is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, |
| 236 | # C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make |
| 237 | # doxygen treat .inc files as Fortran files (default is PHP), and .f files as C |
| 238 | # (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions |
| 239 | # you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. |
| 240 | |
| 241 | EXTENSION_MAPPING = |
| 242 | |
| 243 | # If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all |
| 244 | # comments according to the Markdown format, which allows for more readable |
| 245 | # documentation. See http://daringfireball.net/projects/markdown/ for details. |
| 246 | # The output of markdown processing is further processed by doxygen, so you |
| 247 | # can mix doxygen, HTML, and XML commands with Markdown formatting. |
| 248 | # Disable only in case of backward compatibilities issues. |
| 249 | |
| 250 | MARKDOWN_SUPPORT = YES |
| 251 | |
| 252 | # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want |
| 253 | # to include (a tag file for) the STL sources as input, then you should |
| 254 | # set this tag to YES in order to let doxygen match functions declarations and |
| 255 | # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. |
| 256 | # func(std::string) {}). This also makes the inheritance and collaboration |
| 257 | # diagrams that involve STL classes more complete and accurate. |
| 258 | |
| 259 | BUILTIN_STL_SUPPORT = YES |
| 260 | |
| 261 | # If you use Microsoft's C++/CLI language, you should set this option to YES to |
| 262 | # enable parsing support. |
| 263 | |
| 264 | CPP_CLI_SUPPORT = NO |
| 265 | |
| 266 | # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. |
| 267 | # Doxygen will parse them like normal C++ but will assume all classes use public |
| 268 | # instead of private inheritance when no explicit protection keyword is present. |
| 269 | |
| 270 | SIP_SUPPORT = NO |
| 271 | |
| 272 | # For Microsoft's IDL there are propget and propput attributes to indicate getter |
| 273 | # and setter methods for a property. Setting this option to YES (the default) |
| 274 | # will make doxygen replace the get and set methods by a property in the |
| 275 | # documentation. This will only work if the methods are indeed getting or |
| 276 | # setting a simple type. If this is not the case, or you want to show the |
| 277 | # methods anyway, you should set this option to NO. |
| 278 | |
| 279 | IDL_PROPERTY_SUPPORT = YES |
| 280 | |
| 281 | # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC |
| 282 | # tag is set to YES, then doxygen will reuse the documentation of the first |
| 283 | # member in the group (if any) for the other members of the group. By default |
| 284 | # all members of a group must be documented explicitly. |
| 285 | |
| 286 | DISTRIBUTE_GROUP_DOC = NO |
| 287 | |
| 288 | # Set the SUBGROUPING tag to YES (the default) to allow class member groups of |
| 289 | # the same type (for instance a group of public functions) to be put as a |
| 290 | # subgroup of that type (e.g. under the Public Functions section). Set it to |
| 291 | # NO to prevent subgrouping. Alternatively, this can be done per class using |
| 292 | # the \nosubgrouping command. |
| 293 | |
| 294 | SUBGROUPING = YES |
| 295 | |
| 296 | # When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and |
| 297 | # unions are shown inside the group in which they are included (e.g. using |
| 298 | # @ingroup) instead of on a separate page (for HTML and Man pages) or |
| 299 | # section (for LaTeX and RTF). |
| 300 | |
| 301 | INLINE_GROUPED_CLASSES = NO |
| 302 | |
| 303 | # When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and |
| 304 | # unions with only public data fields will be shown inline in the documentation |
| 305 | # of the scope in which they are defined (i.e. file, namespace, or group |
| 306 | # documentation), provided this scope is documented. If set to NO (the default), |
| 307 | # structs, classes, and unions are shown on a separate page (for HTML and Man |
| 308 | # pages) or section (for LaTeX and RTF). |
| 309 | |
| 310 | INLINE_SIMPLE_STRUCTS = NO |
| 311 | |
| 312 | # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum |
| 313 | # is documented as struct, union, or enum with the name of the typedef. So |
| 314 | # typedef struct TypeS {} TypeT, will appear in the documentation as a struct |
| 315 | # with name TypeT. When disabled the typedef will appear as a member of a file, |
| 316 | # namespace, or class. And the struct will be named TypeS. This can typically |
| 317 | # be useful for C code in case the coding convention dictates that all compound |
| 318 | # types are typedef'ed and only the typedef is referenced, never the tag name. |
| 319 | |
| 320 | TYPEDEF_HIDES_STRUCT = NO |
| 321 | |
| 322 | # The SYMBOL_CACHE_SIZE determines the size of the internal cache use to |
| 323 | # determine which symbols to keep in memory and which to flush to disk. |
| 324 | # When the cache is full, less often used symbols will be written to disk. |
| 325 | # For small to medium size projects (<1000 input files) the default value is |
| 326 | # probably good enough. For larger projects a too small cache size can cause |
| 327 | # doxygen to be busy swapping symbols to and from disk most of the time |
| 328 | # causing a significant performance penalty. |
| 329 | # If the system has enough physical memory increasing the cache will improve the |
| 330 | # performance by keeping more symbols in memory. Note that the value works on |
| 331 | # a logarithmic scale so increasing the size by one will roughly double the |
| 332 | # memory usage. The cache size is given by this formula: |
| 333 | # 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, |
| 334 | # corresponding to a cache size of 2^16 = 65536 symbols. |
| 335 | |
| 336 | SYMBOL_CACHE_SIZE = 0 |
| 337 | |
| 338 | # Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be |
| 339 | # set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given |
| 340 | # their name and scope. Since this can be an expensive process and often the |
| 341 | # same symbol appear multiple times in the code, doxygen keeps a cache of |
| 342 | # pre-resolved symbols. If the cache is too small doxygen will become slower. |
| 343 | # If the cache is too large, memory is wasted. The cache size is given by this |
| 344 | # formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, |
| 345 | # corresponding to a cache size of 2^16 = 65536 symbols. |
| 346 | |
| 347 | LOOKUP_CACHE_SIZE = 0 |
| 348 | |
| 349 | #--------------------------------------------------------------------------- |
| 350 | # Build related configuration options |
| 351 | #--------------------------------------------------------------------------- |
| 352 | |
| 353 | # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in |
| 354 | # documentation are documented, even if no documentation was available. |
| 355 | # Private class members and static file members will be hidden unless |
| 356 | # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES |
| 357 | |
| 358 | EXTRACT_ALL = NO |
| 359 | |
| 360 | # If the EXTRACT_PRIVATE tag is set to YES all private members of a class |
| 361 | # will be included in the documentation. |
| 362 | |
| 363 | EXTRACT_PRIVATE = NO |
| 364 | |
| 365 | # If the EXTRACT_PACKAGE tag is set to YES all members with package or internal scope will be included in the documentation. |
| 366 | |
| 367 | EXTRACT_PACKAGE = NO |
| 368 | |
| 369 | # If the EXTRACT_STATIC tag is set to YES all static members of a file |
| 370 | # will be included in the documentation. |
| 371 | |
| 372 | EXTRACT_STATIC = NO |
| 373 | |
| 374 | # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) |
| 375 | # defined locally in source files will be included in the documentation. |
| 376 | # If set to NO only classes defined in header files are included. |
| 377 | |
| 378 | EXTRACT_LOCAL_CLASSES = NO |
| 379 | |
| 380 | # This flag is only useful for Objective-C code. When set to YES local |
| 381 | # methods, which are defined in the implementation section but not in |
| 382 | # the interface are included in the documentation. |
| 383 | # If set to NO (the default) only methods in the interface are included. |
| 384 | |
| 385 | EXTRACT_LOCAL_METHODS = NO |
| 386 | |
| 387 | # If this flag is set to YES, the members of anonymous namespaces will be |
| 388 | # extracted and appear in the documentation as a namespace called |
| 389 | # 'anonymous_namespace{file}', where file will be replaced with the base |
| 390 | # name of the file that contains the anonymous namespace. By default |
| 391 | # anonymous namespaces are hidden. |
| 392 | |
| 393 | EXTRACT_ANON_NSPACES = NO |
| 394 | |
| 395 | # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all |
| 396 | # undocumented members of documented classes, files or namespaces. |
| 397 | # If set to NO (the default) these members will be included in the |
| 398 | # various overviews, but no documentation section is generated. |
| 399 | # This option has no effect if EXTRACT_ALL is enabled. |
| 400 | |
| 401 | HIDE_UNDOC_MEMBERS = YES |
| 402 | |
| 403 | # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all |
| 404 | # undocumented classes that are normally visible in the class hierarchy. |
| 405 | # If set to NO (the default) these classes will be included in the various |
| 406 | # overviews. This option has no effect if EXTRACT_ALL is enabled. |
| 407 | |
| 408 | HIDE_UNDOC_CLASSES = YES |
| 409 | |
| 410 | # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all |
| 411 | # friend (class|struct|union) declarations. |
| 412 | # If set to NO (the default) these declarations will be included in the |
| 413 | # documentation. |
| 414 | |
| 415 | HIDE_FRIEND_COMPOUNDS = NO |
| 416 | |
| 417 | # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any |
| 418 | # documentation blocks found inside the body of a function. |
| 419 | # If set to NO (the default) these blocks will be appended to the |
| 420 | # function's detailed documentation block. |
| 421 | |
| 422 | HIDE_IN_BODY_DOCS = NO |
| 423 | |
| 424 | # The INTERNAL_DOCS tag determines if documentation |
| 425 | # that is typed after a \internal command is included. If the tag is set |
| 426 | # to NO (the default) then the documentation will be excluded. |
| 427 | # Set it to YES to include the internal documentation. |
| 428 | |
| 429 | INTERNAL_DOCS = YES |
| 430 | |
| 431 | # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate |
| 432 | # file names in lower-case letters. If set to YES upper-case letters are also |
| 433 | # allowed. This is useful if you have classes or files whose names only differ |
| 434 | # in case and if your file system supports case sensitive file names. Windows |
| 435 | # and Mac users are advised to set this option to NO. |
| 436 | |
| 437 | CASE_SENSE_NAMES = NO |
| 438 | |
| 439 | # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen |
| 440 | # will show members with their full class and namespace scopes in the |
| 441 | # documentation. If set to YES the scope will be hidden. |
| 442 | |
| 443 | HIDE_SCOPE_NAMES = NO |
| 444 | |
| 445 | # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen |
| 446 | # will put a list of the files that are included by a file in the documentation |
| 447 | # of that file. |
| 448 | |
| 449 | SHOW_INCLUDE_FILES = YES |
| 450 | |
| 451 | # If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen |
| 452 | # will list include files with double quotes in the documentation |
| 453 | # rather than with sharp brackets. |
| 454 | |
| 455 | FORCE_LOCAL_INCLUDES = YES |
| 456 | |
| 457 | # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] |
| 458 | # is inserted in the documentation for inline members. |
| 459 | |
| 460 | INLINE_INFO = NO |
| 461 | |
| 462 | # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen |
| 463 | # will sort the (detailed) documentation of file and class members |
| 464 | # alphabetically by member name. If set to NO the members will appear in |
| 465 | # declaration order. |
| 466 | |
| 467 | SORT_MEMBER_DOCS = NO |
| 468 | |
| 469 | # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the |
| 470 | # brief documentation of file, namespace and class members alphabetically |
| 471 | # by member name. If set to NO (the default) the members will appear in |
| 472 | # declaration order. |
| 473 | |
| 474 | SORT_BRIEF_DOCS = NO |
| 475 | |
| 476 | # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen |
| 477 | # will sort the (brief and detailed) documentation of class members so that |
| 478 | # constructors and destructors are listed first. If set to NO (the default) |
| 479 | # the constructors will appear in the respective orders defined by |
| 480 | # SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. |
| 481 | # This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO |
| 482 | # and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. |
| 483 | |
| 484 | SORT_MEMBERS_CTORS_1ST = NO |
| 485 | |
| 486 | # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the |
| 487 | # hierarchy of group names into alphabetical order. If set to NO (the default) |
| 488 | # the group names will appear in their defined order. |
| 489 | |
| 490 | SORT_GROUP_NAMES = YES |
| 491 | |
| 492 | # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be |
| 493 | # sorted by fully-qualified names, including namespaces. If set to |
| 494 | # NO (the default), the class list will be sorted only by class name, |
| 495 | # not including the namespace part. |
| 496 | # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. |
| 497 | # Note: This option applies only to the class list, not to the |
| 498 | # alphabetical list. |
| 499 | |
| 500 | SORT_BY_SCOPE_NAME = YES |
| 501 | |
| 502 | # If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to |
| 503 | # do proper type resolution of all parameters of a function it will reject a |
| 504 | # match between the prototype and the implementation of a member function even |
| 505 | # if there is only one candidate or it is obvious which candidate to choose |
| 506 | # by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen |
| 507 | # will still accept a match between prototype and implementation in such cases. |
| 508 | |
| 509 | STRICT_PROTO_MATCHING = NO |
| 510 | |
| 511 | # The GENERATE_TODOLIST tag can be used to enable (YES) or |
| 512 | # disable (NO) the todo list. This list is created by putting \todo |
| 513 | # commands in the documentation. |
| 514 | |
| 515 | GENERATE_TODOLIST = YES |
| 516 | |
| 517 | # The GENERATE_TESTLIST tag can be used to enable (YES) or |
| 518 | # disable (NO) the test list. This list is created by putting \test |
| 519 | # commands in the documentation. |
| 520 | |
| 521 | GENERATE_TESTLIST = YES |
| 522 | |
| 523 | # The GENERATE_BUGLIST tag can be used to enable (YES) or |
| 524 | # disable (NO) the bug list. This list is created by putting \bug |
| 525 | # commands in the documentation. |
| 526 | |
| 527 | GENERATE_BUGLIST = YES |
| 528 | |
| 529 | # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or |
| 530 | # disable (NO) the deprecated list. This list is created by putting |
| 531 | # \deprecated commands in the documentation. |
| 532 | |
| 533 | GENERATE_DEPRECATEDLIST= YES |
| 534 | |
| 535 | # The ENABLED_SECTIONS tag can be used to enable conditional |
| 536 | # documentation sections, marked by \if sectionname ... \endif. |
| 537 | |
| 538 | ENABLED_SECTIONS = |
| 539 | |
| 540 | # The MAX_INITIALIZER_LINES tag determines the maximum number of lines |
| 541 | # the initial value of a variable or macro consists of for it to appear in |
| 542 | # the documentation. If the initializer consists of more lines than specified |
| 543 | # here it will be hidden. Use a value of 0 to hide initializers completely. |
| 544 | # The appearance of the initializer of individual variables and macros in the |
| 545 | # documentation can be controlled using \showinitializer or \hideinitializer |
| 546 | # command in the documentation regardless of this setting. |
| 547 | |
| 548 | MAX_INITIALIZER_LINES = 30 |
| 549 | |
| 550 | # Set the SHOW_USED_FILES tag to NO to disable the list of files generated |
| 551 | # at the bottom of the documentation of classes and structs. If set to YES the |
| 552 | # list will mention the files that were used to generate the documentation. |
| 553 | |
| 554 | SHOW_USED_FILES = YES |
| 555 | |
| 556 | # Set the SHOW_FILES tag to NO to disable the generation of the Files page. |
| 557 | # This will remove the Files entry from the Quick Index and from the |
| 558 | # Folder Tree View (if specified). The default is YES. |
| 559 | |
| 560 | SHOW_FILES = YES |
| 561 | |
| 562 | # Set the SHOW_NAMESPACES tag to NO to disable the generation of the |
| 563 | # Namespaces page. |
| 564 | # This will remove the Namespaces entry from the Quick Index |
| 565 | # and from the Folder Tree View (if specified). The default is YES. |
| 566 | |
| 567 | SHOW_NAMESPACES = YES |
| 568 | |
| 569 | # The FILE_VERSION_FILTER tag can be used to specify a program or script that |
| 570 | # doxygen should invoke to get the current version for each file (typically from |
| 571 | # the version control system). Doxygen will invoke the program by executing (via |
| 572 | # popen()) the command <command> <input-file>, where <command> is the value of |
| 573 | # the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file |
| 574 | # provided by doxygen. Whatever the program writes to standard output |
| 575 | # is used as the file version. See the manual for examples. |
| 576 | |
| 577 | FILE_VERSION_FILTER = |
| 578 | |
| 579 | # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed |
| 580 | # by doxygen. The layout file controls the global structure of the generated |
| 581 | # output files in an output format independent way. To create the layout file |
| 582 | # that represents doxygen's defaults, run doxygen with the -l option. |
| 583 | # You can optionally specify a file name after the option, if omitted |
| 584 | # DoxygenLayout.xml will be used as the name of the layout file. |
| 585 | |
| 586 | LAYOUT_FILE = |
| 587 | |
| 588 | # The CITE_BIB_FILES tag can be used to specify one or more bib files |
| 589 | # containing the references data. This must be a list of .bib files. The |
| 590 | # .bib extension is automatically appended if omitted. Using this command |
| 591 | # requires the bibtex tool to be installed. See also |
| 592 | # http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style |
| 593 | # of the bibliography can be controlled using LATEX_BIB_STYLE. To use this |
| 594 | # feature you need bibtex and perl available in the search path. |
| 595 | |
| 596 | CITE_BIB_FILES = |
| 597 | |
| 598 | #--------------------------------------------------------------------------- |
| 599 | # configuration options related to warning and progress messages |
| 600 | #--------------------------------------------------------------------------- |
| 601 | |
| 602 | # The QUIET tag can be used to turn on/off the messages that are generated |
| 603 | # by doxygen. Possible values are YES and NO. If left blank NO is used. |
| 604 | |
| 605 | QUIET = YES |
| 606 | |
| 607 | # The WARNINGS tag can be used to turn on/off the warning messages that are |
| 608 | # generated by doxygen. Possible values are YES and NO. If left blank |
| 609 | # NO is used. |
| 610 | |
| 611 | WARNINGS = YES |
| 612 | |
| 613 | # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings |
| 614 | # for undocumented members. If EXTRACT_ALL is set to YES then this flag will |
| 615 | # automatically be disabled. |
| 616 | |
| 617 | WARN_IF_UNDOCUMENTED = YES |
| 618 | |
| 619 | # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for |
| 620 | # potential errors in the documentation, such as not documenting some |
| 621 | # parameters in a documented function, or documenting parameters that |
| 622 | # don't exist or using markup commands wrongly. |
| 623 | |
| 624 | WARN_IF_DOC_ERROR = YES |
| 625 | |
| 626 | # The WARN_NO_PARAMDOC option can be enabled to get warnings for |
| 627 | # functions that are documented, but have no documentation for their parameters |
| 628 | # or return value. If set to NO (the default) doxygen will only warn about |
| 629 | # wrong or incomplete parameter documentation, but not about the absence of |
| 630 | # documentation. |
| 631 | |
| 632 | WARN_NO_PARAMDOC = YES |
| 633 | |
| 634 | # The WARN_FORMAT tag determines the format of the warning messages that |
| 635 | # doxygen can produce. The string should contain the $file, $line, and $text |
| 636 | # tags, which will be replaced by the file and line number from which the |
| 637 | # warning originated and the warning text. Optionally the format may contain |
| 638 | # $version, which will be replaced by the version of the file (if it could |
| 639 | # be obtained via FILE_VERSION_FILTER) |
| 640 | |
| 641 | WARN_FORMAT = "$file:$line: $text" |
| 642 | |
| 643 | # The WARN_LOGFILE tag can be used to specify a file to which warning |
| 644 | # and error messages should be written. If left blank the output is written |
| 645 | # to stderr. |
| 646 | |
| 647 | WARN_LOGFILE = |
| 648 | |
| 649 | #--------------------------------------------------------------------------- |
| 650 | # configuration options related to the input files |
| 651 | #--------------------------------------------------------------------------- |
| 652 | |
| 653 | # The INPUT tag can be used to specify the files and/or directories that contain |
| 654 | # documented source files. You may enter file names like "myfile.cpp" or |
| 655 | # directories like "/usr/src/myproject". Separate the files or directories |
| 656 | # with spaces. |
| 657 | |
| 658 | INPUT = LuaBridge.h \ |
| 659 | RefCountedObject.h \ |
| 660 | RefCountedPtr.h |
| 661 | |
| 662 | # This tag can be used to specify the character encoding of the source files |
| 663 | # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is |
| 664 | # also the default input encoding. Doxygen uses libiconv (or the iconv built |
| 665 | # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for |
| 666 | # the list of possible encodings. |
| 667 | |
| 668 | INPUT_ENCODING = UTF-8 |
| 669 | |
| 670 | # If the value of the INPUT tag contains directories, you can use the |
| 671 | # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp |
| 672 | # and *.h) to filter out the source-files in the directories. If left |
| 673 | # blank the following patterns are tested: |
| 674 | # *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh |
| 675 | # *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py |
| 676 | # *.f90 *.f *.for *.vhd *.vhdl |
| 677 | |
| 678 | FILE_PATTERNS = *.c \ |
| 679 | *.cpp \ |
| 680 | *.h \ |
| 681 | *.hpp |
| 682 | |
| 683 | # The RECURSIVE tag can be used to turn specify whether or not subdirectories |
| 684 | # should be searched for input files as well. Possible values are YES and NO. |
| 685 | # If left blank NO is used. |
| 686 | |
| 687 | RECURSIVE = YES |
| 688 | |
| 689 | # The EXCLUDE tag can be used to specify files and/or directories that should be |
| 690 | # excluded from the INPUT source files. This way you can easily exclude a |
| 691 | # subdirectory from a directory tree whose root is specified with the INPUT tag. |
| 692 | # Note that relative paths are relative to the directory from which doxygen is |
| 693 | # run. |
| 694 | |
| 695 | EXCLUDE = |
| 696 | |
| 697 | # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or |
| 698 | # directories that are symbolic links (a Unix file system feature) are excluded |
| 699 | # from the input. |
| 700 | |
| 701 | EXCLUDE_SYMLINKS = NO |
| 702 | |
| 703 | # If the value of the INPUT tag contains directories, you can use the |
| 704 | # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude |
| 705 | # certain files from those directories. Note that the wildcards are matched |
| 706 | # against the file with absolute path, so to exclude all test directories |
| 707 | # for example use the pattern */test/* |
| 708 | |
| 709 | EXCLUDE_PATTERNS = |
| 710 | |
| 711 | # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names |
| 712 | # (namespaces, classes, functions, etc.) that should be excluded from the |
| 713 | # output. The symbol name can be a fully qualified name, a word, or if the |
| 714 | # wildcard * is used, a substring. Examples: ANamespace, AClass, |
| 715 | # AClass::ANamespace, ANamespace::*Test |
| 716 | |
| 717 | EXCLUDE_SYMBOLS = |
| 718 | |
| 719 | # The EXAMPLE_PATH tag can be used to specify one or more files or |
| 720 | # directories that contain example code fragments that are included (see |
| 721 | # the \include command). |
| 722 | |
| 723 | EXAMPLE_PATH = ./ |
| 724 | |
| 725 | # If the value of the EXAMPLE_PATH tag contains directories, you can use the |
| 726 | # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp |
| 727 | # and *.h) to filter out the source-files in the directories. If left |
| 728 | # blank all files are included. |
| 729 | |
| 730 | EXAMPLE_PATTERNS = * |
| 731 | |
| 732 | # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be |
| 733 | # searched for input files to be used with the \include or \dontinclude |
| 734 | # commands irrespective of the value of the RECURSIVE tag. |
| 735 | # Possible values are YES and NO. If left blank NO is used. |
| 736 | |
| 737 | EXAMPLE_RECURSIVE = NO |
| 738 | |
| 739 | # The IMAGE_PATH tag can be used to specify one or more files or |
| 740 | # directories that contain image that are included in the documentation (see |
| 741 | # the \image command). |
| 742 | |
| 743 | IMAGE_PATH = |
| 744 | |
| 745 | # The INPUT_FILTER tag can be used to specify a program that doxygen should |
| 746 | # invoke to filter for each input file. Doxygen will invoke the filter program |
| 747 | # by executing (via popen()) the command <filter> <input-file>, where <filter> |
| 748 | # is the value of the INPUT_FILTER tag, and <input-file> is the name of an |
| 749 | # input file. Doxygen will then use the output that the filter program writes |
| 750 | # to standard output. |
| 751 | # If FILTER_PATTERNS is specified, this tag will be |
| 752 | # ignored. |
| 753 | |
| 754 | INPUT_FILTER = |
| 755 | |
| 756 | # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern |
| 757 | # basis. |
| 758 | # Doxygen will compare the file name with each pattern and apply the |
| 759 | # filter if there is a match. |
| 760 | # The filters are a list of the form: |
| 761 | # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further |
| 762 | # info on how filters are used. If FILTER_PATTERNS is empty or if |
| 763 | # non of the patterns match the file name, INPUT_FILTER is applied. |
| 764 | |
| 765 | FILTER_PATTERNS = |
| 766 | |
| 767 | # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using |
| 768 | # INPUT_FILTER) will be used to filter the input files when producing source |
| 769 | # files to browse (i.e. when SOURCE_BROWSER is set to YES). |
| 770 | |
| 771 | FILTER_SOURCE_FILES = NO |
| 772 | |
| 773 | # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file |
| 774 | # pattern. A pattern will override the setting for FILTER_PATTERN (if any) |
| 775 | # and it is also possible to disable source filtering for a specific pattern |
| 776 | # using *.ext= (so without naming a filter). This option only has effect when |
| 777 | # FILTER_SOURCE_FILES is enabled. |
| 778 | |
| 779 | FILTER_SOURCE_PATTERNS = |
| 780 | |
| 781 | #--------------------------------------------------------------------------- |
| 782 | # configuration options related to source browsing |
| 783 | #--------------------------------------------------------------------------- |
| 784 | |
| 785 | # If the SOURCE_BROWSER tag is set to YES then a list of source files will |
| 786 | # be generated. Documented entities will be cross-referenced with these sources. |
| 787 | # Note: To get rid of all source code in the generated output, make sure also |
| 788 | # VERBATIM_HEADERS is set to NO. |
| 789 | |
| 790 | SOURCE_BROWSER = YES |
| 791 | |
| 792 | # Setting the INLINE_SOURCES tag to YES will include the body |
| 793 | # of functions and classes directly in the documentation. |
| 794 | |
| 795 | INLINE_SOURCES = NO |
| 796 | |
| 797 | # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct |
| 798 | # doxygen to hide any special comment blocks from generated source code |
| 799 | # fragments. Normal C, C++ and Fortran comments will always remain visible. |
| 800 | |
| 801 | STRIP_CODE_COMMENTS = NO |
| 802 | |
| 803 | # If the REFERENCED_BY_RELATION tag is set to YES |
| 804 | # then for each documented function all documented |
| 805 | # functions referencing it will be listed. |
| 806 | |
| 807 | REFERENCED_BY_RELATION = NO |
| 808 | |
| 809 | # If the REFERENCES_RELATION tag is set to YES |
| 810 | # then for each documented function all documented entities |
| 811 | # called/used by that function will be listed. |
| 812 | |
| 813 | REFERENCES_RELATION = NO |
| 814 | |
| 815 | # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) |
| 816 | # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from |
| 817 | # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will |
| 818 | # link to the source code. |
| 819 | # Otherwise they will link to the documentation. |
| 820 | |
| 821 | REFERENCES_LINK_SOURCE = YES |
| 822 | |
| 823 | # If the USE_HTAGS tag is set to YES then the references to source code |
| 824 | # will point to the HTML generated by the htags(1) tool instead of doxygen |
| 825 | # built-in source browser. The htags tool is part of GNU's global source |
| 826 | # tagging system (see http://www.gnu.org/software/global/global.html). You |
| 827 | # will need version 4.8.6 or higher. |
| 828 | |
| 829 | USE_HTAGS = NO |
| 830 | |
| 831 | # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen |
| 832 | # will generate a verbatim copy of the header file for each class for |
| 833 | # which an include is specified. Set to NO to disable this. |
| 834 | |
| 835 | VERBATIM_HEADERS = NO |
| 836 | |
| 837 | #--------------------------------------------------------------------------- |
| 838 | # configuration options related to the alphabetical class index |
| 839 | #--------------------------------------------------------------------------- |
| 840 | |
| 841 | # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index |
| 842 | # of all compounds will be generated. Enable this if the project |
| 843 | # contains a lot of classes, structs, unions or interfaces. |
| 844 | |
| 845 | ALPHABETICAL_INDEX = NO |
| 846 | |
| 847 | # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then |
| 848 | # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns |
| 849 | # in which this list will be split (can be a number in the range [1..20]) |
| 850 | |
| 851 | COLS_IN_ALPHA_INDEX = 5 |
| 852 | |
| 853 | # In case all classes in a project start with a common prefix, all |
| 854 | # classes will be put under the same header in the alphabetical index. |
| 855 | # The IGNORE_PREFIX tag can be used to specify one or more prefixes that |
| 856 | # should be ignored while generating the index headers. |
| 857 | |
| 858 | IGNORE_PREFIX = |
| 859 | |
| 860 | #--------------------------------------------------------------------------- |
| 861 | # configuration options related to the HTML output |
| 862 | #--------------------------------------------------------------------------- |
| 863 | |
| 864 | # If the GENERATE_HTML tag is set to YES (the default) Doxygen will |
| 865 | # generate HTML output. |
| 866 | |
| 867 | GENERATE_HTML = YES |
| 868 | |
| 869 | # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. |
| 870 | # If a relative path is entered the value of OUTPUT_DIRECTORY will be |
| 871 | # put in front of it. If left blank `html' will be used as the default path. |
| 872 | |
| 873 | HTML_OUTPUT = Documentation |
| 874 | |
| 875 | # The HTML_FILE_EXTENSION tag can be used to specify the file extension for |
| 876 | # each generated HTML page (for example: .htm,.php,.asp). If it is left blank |
| 877 | # doxygen will generate files with .html extension. |
| 878 | |
| 879 | HTML_FILE_EXTENSION = .html |
| 880 | |
| 881 | # The HTML_HEADER tag can be used to specify a personal HTML header for |
| 882 | # each generated HTML page. If it is left blank doxygen will generate a |
| 883 | # standard header. Note that when using a custom header you are responsible |
| 884 | # for the proper inclusion of any scripts and style sheets that doxygen |
| 885 | # needs, which is dependent on the configuration options used. |
| 886 | # It is advised to generate a default header using "doxygen -w html |
| 887 | # header.html footer.html stylesheet.css YourConfigFile" and then modify |
| 888 | # that header. Note that the header is subject to change so you typically |
| 889 | # have to redo this when upgrading to a newer version of doxygen or when |
| 890 | # changing the value of configuration settings such as GENERATE_TREEVIEW! |
| 891 | |
| 892 | HTML_HEADER = |
| 893 | |
| 894 | # The HTML_FOOTER tag can be used to specify a personal HTML footer for |
| 895 | # each generated HTML page. If it is left blank doxygen will generate a |
| 896 | # standard footer. |
| 897 | |
| 898 | HTML_FOOTER = |
| 899 | |
| 900 | # The HTML_STYLESHEET tag can be used to specify a user-defined cascading |
| 901 | # style sheet that is used by each HTML page. It can be used to |
| 902 | # fine-tune the look of the HTML output. If the tag is left blank doxygen |
| 903 | # will generate a default style sheet. Note that doxygen will try to copy |
| 904 | # the style sheet file to the HTML output directory, so don't put your own |
| 905 | # style sheet in the HTML output directory as well, or it will be erased! |
| 906 | |
| 907 | HTML_STYLESHEET = |
| 908 | |
| 909 | # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or |
| 910 | # other source files which should be copied to the HTML output directory. Note |
| 911 | # that these files will be copied to the base HTML output directory. Use the |
| 912 | # $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these |
| 913 | # files. In the HTML_STYLESHEET file, use the file name only. Also note that |
| 914 | # the files will be copied as-is; there are no commands or markers available. |
| 915 | |
| 916 | HTML_EXTRA_FILES = |
| 917 | |
| 918 | # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. |
| 919 | # Doxygen will adjust the colors in the style sheet and background images |
| 920 | # according to this color. Hue is specified as an angle on a colorwheel, |
| 921 | # see http://en.wikipedia.org/wiki/Hue for more information. |
| 922 | # For instance the value 0 represents red, 60 is yellow, 120 is green, |
| 923 | # 180 is cyan, 240 is blue, 300 purple, and 360 is red again. |
| 924 | # The allowed range is 0 to 359. |
| 925 | |
| 926 | HTML_COLORSTYLE_HUE = 240 |
| 927 | |
| 928 | # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of |
| 929 | # the colors in the HTML output. For a value of 0 the output will use |
| 930 | # grayscales only. A value of 255 will produce the most vivid colors. |
| 931 | |
| 932 | HTML_COLORSTYLE_SAT = 64 |
| 933 | |
| 934 | # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to |
| 935 | # the luminance component of the colors in the HTML output. Values below |
| 936 | # 100 gradually make the output lighter, whereas values above 100 make |
| 937 | # the output darker. The value divided by 100 is the actual gamma applied, |
| 938 | # so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, |
| 939 | # and 100 does not change the gamma. |
| 940 | |
| 941 | HTML_COLORSTYLE_GAMMA = 80 |
| 942 | |
| 943 | # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML |
| 944 | # page will contain the date and time when the page was generated. Setting |
| 945 | # this to NO can help when comparing the output of multiple runs. |
| 946 | |
| 947 | HTML_TIMESTAMP = NO |
| 948 | |
| 949 | # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML |
| 950 | # documentation will contain sections that can be hidden and shown after the |
| 951 | # page has loaded. |
| 952 | |
| 953 | HTML_DYNAMIC_SECTIONS = NO |
| 954 | |
| 955 | # With HTML_INDEX_NUM_ENTRIES one can control the preferred number of |
| 956 | # entries shown in the various tree structured indices initially; the user |
| 957 | # can expand and collapse entries dynamically later on. Doxygen will expand |
| 958 | # the tree to such a level that at most the specified number of entries are |
| 959 | # visible (unless a fully collapsed tree already exceeds this amount). |
| 960 | # So setting the number of entries 1 will produce a full collapsed tree by |
| 961 | # default. 0 is a special value representing an infinite number of entries |
| 962 | # and will result in a full expanded tree by default. |
| 963 | |
| 964 | HTML_INDEX_NUM_ENTRIES = 100 |
| 965 | |
| 966 | # If the GENERATE_DOCSET tag is set to YES, additional index files |
| 967 | # will be generated that can be used as input for Apple's Xcode 3 |
| 968 | # integrated development environment, introduced with OSX 10.5 (Leopard). |
| 969 | # To create a documentation set, doxygen will generate a Makefile in the |
| 970 | # HTML output directory. Running make will produce the docset in that |
| 971 | # directory and running "make install" will install the docset in |
| 972 | # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find |
| 973 | # it at startup. |
| 974 | # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html |
| 975 | # for more information. |
| 976 | |
| 977 | GENERATE_DOCSET = NO |
| 978 | |
| 979 | # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the |
| 980 | # feed. A documentation feed provides an umbrella under which multiple |
| 981 | # documentation sets from a single provider (such as a company or product suite) |
| 982 | # can be grouped. |
| 983 | |
| 984 | DOCSET_FEEDNAME = "Doxygen generated docs" |
| 985 | |
| 986 | # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that |
| 987 | # should uniquely identify the documentation set bundle. This should be a |
| 988 | # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen |
| 989 | # will append .docset to the name. |
| 990 | |
| 991 | DOCSET_BUNDLE_ID = org.doxygen.Project |
| 992 | |
| 993 | # When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify |
| 994 | # the documentation publisher. This should be a reverse domain-name style |
| 995 | # string, e.g. com.mycompany.MyDocSet.documentation. |
| 996 | |
| 997 | DOCSET_PUBLISHER_ID = org.doxygen.Publisher |
| 998 | |
| 999 | # The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. |
| 1000 | |
| 1001 | DOCSET_PUBLISHER_NAME = Publisher |
| 1002 | |
| 1003 | # If the GENERATE_HTMLHELP tag is set to YES, additional index files |
| 1004 | # will be generated that can be used as input for tools like the |
| 1005 | # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) |
| 1006 | # of the generated HTML documentation. |
| 1007 | |
| 1008 | GENERATE_HTMLHELP = NO |
| 1009 | |
| 1010 | # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can |
| 1011 | # be used to specify the file name of the resulting .chm file. You |
| 1012 | # can add a path in front of the file if the result should not be |
| 1013 | # written to the html output directory. |
| 1014 | |
| 1015 | CHM_FILE = |
| 1016 | |
| 1017 | # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can |
| 1018 | # be used to specify the location (absolute path including file name) of |
| 1019 | # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run |
| 1020 | # the HTML help compiler on the generated index.hhp. |
| 1021 | |
| 1022 | HHC_LOCATION = |
| 1023 | |
| 1024 | # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag |
| 1025 | # controls if a separate .chi index file is generated (YES) or that |
| 1026 | # it should be included in the master .chm file (NO). |
| 1027 | |
| 1028 | GENERATE_CHI = NO |
| 1029 | |
| 1030 | # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING |
| 1031 | # is used to encode HtmlHelp index (hhk), content (hhc) and project file |
| 1032 | # content. |
| 1033 | |
| 1034 | CHM_INDEX_ENCODING = |
| 1035 | |
| 1036 | # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag |
| 1037 | # controls whether a binary table of contents is generated (YES) or a |
| 1038 | # normal table of contents (NO) in the .chm file. |
| 1039 | |
| 1040 | BINARY_TOC = NO |
| 1041 | |
| 1042 | # The TOC_EXPAND flag can be set to YES to add extra items for group members |
| 1043 | # to the contents of the HTML help documentation and to the tree view. |
| 1044 | |
| 1045 | TOC_EXPAND = NO |
| 1046 | |
| 1047 | # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and |
| 1048 | # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated |
| 1049 | # that can be used as input for Qt's qhelpgenerator to generate a |
| 1050 | # Qt Compressed Help (.qch) of the generated HTML documentation. |
| 1051 | |
| 1052 | GENERATE_QHP = NO |
| 1053 | |
| 1054 | # If the QHG_LOCATION tag is specified, the QCH_FILE tag can |
| 1055 | # be used to specify the file name of the resulting .qch file. |
| 1056 | # The path specified is relative to the HTML output folder. |
| 1057 | |
| 1058 | QCH_FILE = |
| 1059 | |
| 1060 | # The QHP_NAMESPACE tag specifies the namespace to use when generating |
| 1061 | # Qt Help Project output. For more information please see |
| 1062 | # http://doc.trolltech.com/qthelpproject.html#namespace |
| 1063 | |
| 1064 | QHP_NAMESPACE = org.doxygen.Project |
| 1065 | |
| 1066 | # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating |
| 1067 | # Qt Help Project output. For more information please see |
| 1068 | # http://doc.trolltech.com/qthelpproject.html#virtual-folders |
| 1069 | |
| 1070 | QHP_VIRTUAL_FOLDER = doc |
| 1071 | |
| 1072 | # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to |
| 1073 | # add. For more information please see |
| 1074 | # http://doc.trolltech.com/qthelpproject.html#custom-filters |
| 1075 | |
| 1076 | QHP_CUST_FILTER_NAME = |
| 1077 | |
| 1078 | # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the |
| 1079 | # custom filter to add. For more information please see |
| 1080 | # <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters"> |
| 1081 | # Qt Help Project / Custom Filters</a>. |
| 1082 | |
| 1083 | QHP_CUST_FILTER_ATTRS = |
| 1084 | |
| 1085 | # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this |
| 1086 | # project's |
| 1087 | # filter section matches. |
| 1088 | # <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes"> |
| 1089 | # Qt Help Project / Filter Attributes</a>. |
| 1090 | |
| 1091 | QHP_SECT_FILTER_ATTRS = |
| 1092 | |
| 1093 | # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can |
| 1094 | # be used to specify the location of Qt's qhelpgenerator. |
| 1095 | # If non-empty doxygen will try to run qhelpgenerator on the generated |
| 1096 | # .qhp file. |
| 1097 | |
| 1098 | QHG_LOCATION = |
| 1099 | |
| 1100 | # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files |
| 1101 | # will be generated, which together with the HTML files, form an Eclipse help |
| 1102 | # plugin. To install this plugin and make it available under the help contents |
| 1103 | # menu in Eclipse, the contents of the directory containing the HTML and XML |
| 1104 | # files needs to be copied into the plugins directory of eclipse. The name of |
| 1105 | # the directory within the plugins directory should be the same as |
| 1106 | # the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before |
| 1107 | # the help appears. |
| 1108 | |
| 1109 | GENERATE_ECLIPSEHELP = NO |
| 1110 | |
| 1111 | # A unique identifier for the eclipse help plugin. When installing the plugin |
| 1112 | # the directory name containing the HTML and XML files should also have |
| 1113 | # this name. |
| 1114 | |
| 1115 | ECLIPSE_DOC_ID = org.doxygen.Project |
| 1116 | |
| 1117 | # The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) |
| 1118 | # at top of each HTML page. The value NO (the default) enables the index and |
| 1119 | # the value YES disables it. Since the tabs have the same information as the |
| 1120 | # navigation tree you can set this option to NO if you already set |
| 1121 | # GENERATE_TREEVIEW to YES. |
| 1122 | |
| 1123 | DISABLE_INDEX = NO |
| 1124 | |
| 1125 | # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index |
| 1126 | # structure should be generated to display hierarchical information. |
| 1127 | # If the tag value is set to YES, a side panel will be generated |
| 1128 | # containing a tree-like index structure (just like the one that |
| 1129 | # is generated for HTML Help). For this to work a browser that supports |
| 1130 | # JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). |
| 1131 | # Windows users are probably better off using the HTML help feature. |
| 1132 | # Since the tree basically has the same information as the tab index you |
| 1133 | # could consider to set DISABLE_INDEX to NO when enabling this option. |
| 1134 | |
| 1135 | GENERATE_TREEVIEW = NO |
| 1136 | |
| 1137 | # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values |
| 1138 | # (range [0,1..20]) that doxygen will group on one line in the generated HTML |
| 1139 | # documentation. Note that a value of 0 will completely suppress the enum |
| 1140 | # values from appearing in the overview section. |
| 1141 | |
| 1142 | ENUM_VALUES_PER_LINE = 4 |
| 1143 | |
| 1144 | # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be |
| 1145 | # used to set the initial width (in pixels) of the frame in which the tree |
| 1146 | # is shown. |
| 1147 | |
| 1148 | TREEVIEW_WIDTH = 250 |
| 1149 | |
| 1150 | # When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open |
| 1151 | # links to external symbols imported via tag files in a separate window. |
| 1152 | |
| 1153 | EXT_LINKS_IN_WINDOW = NO |
| 1154 | |
| 1155 | # Use this tag to change the font size of Latex formulas included |
| 1156 | # as images in the HTML documentation. The default is 10. Note that |
| 1157 | # when you change the font size after a successful doxygen run you need |
| 1158 | # to manually remove any form_*.png images from the HTML output directory |
| 1159 | # to force them to be regenerated. |
| 1160 | |
| 1161 | FORMULA_FONTSIZE = 10 |
| 1162 | |
| 1163 | # Use the FORMULA_TRANPARENT tag to determine whether or not the images |
| 1164 | # generated for formulas are transparent PNGs. Transparent PNGs are |
| 1165 | # not supported properly for IE 6.0, but are supported on all modern browsers. |
| 1166 | # Note that when changing this option you need to delete any form_*.png files |
| 1167 | # in the HTML output before the changes have effect. |
| 1168 | |
| 1169 | FORMULA_TRANSPARENT = YES |
| 1170 | |
| 1171 | # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax |
| 1172 | # (see http://www.mathjax.org) which uses client side Javascript for the |
| 1173 | # rendering instead of using prerendered bitmaps. Use this if you do not |
| 1174 | # have LaTeX installed or if you want to formulas look prettier in the HTML |
| 1175 | # output. When enabled you may also need to install MathJax separately and |
| 1176 | # configure the path to it using the MATHJAX_RELPATH option. |
| 1177 | |
| 1178 | USE_MATHJAX = NO |
| 1179 | |
| 1180 | # When MathJax is enabled you need to specify the location relative to the |
| 1181 | # HTML output directory using the MATHJAX_RELPATH option. The destination |
| 1182 | # directory should contain the MathJax.js script. For instance, if the mathjax |
| 1183 | # directory is located at the same level as the HTML output directory, then |
| 1184 | # MATHJAX_RELPATH should be ../mathjax. The default value points to |
| 1185 | # the MathJax Content Delivery Network so you can quickly see the result without |
| 1186 | # installing MathJax. |
| 1187 | # However, it is strongly recommended to install a local |
| 1188 | # copy of MathJax from http://www.mathjax.org before deployment. |
| 1189 | |
| 1190 | MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest |
| 1191 | |
| 1192 | # The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension |
| 1193 | # names that should be enabled during MathJax rendering. |
| 1194 | |
| 1195 | MATHJAX_EXTENSIONS = |
| 1196 | |
| 1197 | # When the SEARCHENGINE tag is enabled doxygen will generate a search box |
| 1198 | # for the HTML output. The underlying search engine uses javascript |
| 1199 | # and DHTML and should work on any modern browser. Note that when using |
| 1200 | # HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets |
| 1201 | # (GENERATE_DOCSET) there is already a search function so this one should |
| 1202 | # typically be disabled. For large projects the javascript based search engine |
| 1203 | # can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. |
| 1204 | |
| 1205 | SEARCHENGINE = YES |
| 1206 | |
| 1207 | # When the SERVER_BASED_SEARCH tag is enabled the search engine will be |
| 1208 | # implemented using a PHP enabled web server instead of at the web client |
| 1209 | # using Javascript. Doxygen will generate the search PHP script and index |
| 1210 | # file to put on the web server. The advantage of the server |
| 1211 | # based approach is that it scales better to large projects and allows |
| 1212 | # full text search. The disadvantages are that it is more difficult to setup |
| 1213 | # and does not have live searching capabilities. |
| 1214 | |
| 1215 | SERVER_BASED_SEARCH = NO |
| 1216 | |
| 1217 | #--------------------------------------------------------------------------- |
| 1218 | # configuration options related to the LaTeX output |
| 1219 | #--------------------------------------------------------------------------- |
| 1220 | |
| 1221 | # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will |
| 1222 | # generate Latex output. |
| 1223 | |
| 1224 | GENERATE_LATEX = NO |
| 1225 | |
| 1226 | # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. |
| 1227 | # If a relative path is entered the value of OUTPUT_DIRECTORY will be |
| 1228 | # put in front of it. If left blank `latex' will be used as the default path. |
| 1229 | |
| 1230 | LATEX_OUTPUT = latex |
| 1231 | |
| 1232 | # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be |
| 1233 | # invoked. If left blank `latex' will be used as the default command name. |
| 1234 | # Note that when enabling USE_PDFLATEX this option is only used for |
| 1235 | # generating bitmaps for formulas in the HTML output, but not in the |
| 1236 | # Makefile that is written to the output directory. |
| 1237 | |
| 1238 | LATEX_CMD_NAME = latex |
| 1239 | |
| 1240 | # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to |
| 1241 | # generate index for LaTeX. If left blank `makeindex' will be used as the |
| 1242 | # default command name. |
| 1243 | |
| 1244 | MAKEINDEX_CMD_NAME = makeindex |
| 1245 | |
| 1246 | # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact |
| 1247 | # LaTeX documents. This may be useful for small projects and may help to |
| 1248 | # save some trees in general. |
| 1249 | |
| 1250 | COMPACT_LATEX = NO |
| 1251 | |
| 1252 | # The PAPER_TYPE tag can be used to set the paper type that is used |
| 1253 | # by the printer. Possible values are: a4, letter, legal and |
| 1254 | # executive. If left blank a4wide will be used. |
| 1255 | |
| 1256 | PAPER_TYPE = a4 |
| 1257 | |
| 1258 | # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX |
| 1259 | # packages that should be included in the LaTeX output. |
| 1260 | |
| 1261 | EXTRA_PACKAGES = |
| 1262 | |
| 1263 | # The LATEX_HEADER tag can be used to specify a personal LaTeX header for |
| 1264 | # the generated latex document. The header should contain everything until |
| 1265 | # the first chapter. If it is left blank doxygen will generate a |
| 1266 | # standard header. Notice: only use this tag if you know what you are doing! |
| 1267 | |
| 1268 | LATEX_HEADER = |
| 1269 | |
| 1270 | # The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for |
| 1271 | # the generated latex document. The footer should contain everything after |
| 1272 | # the last chapter. If it is left blank doxygen will generate a |
| 1273 | # standard footer. Notice: only use this tag if you know what you are doing! |
| 1274 | |
| 1275 | LATEX_FOOTER = |
| 1276 | |
| 1277 | # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated |
| 1278 | # is prepared for conversion to pdf (using ps2pdf). The pdf file will |
| 1279 | # contain links (just like the HTML output) instead of page references |
| 1280 | # This makes the output suitable for online browsing using a pdf viewer. |
| 1281 | |
| 1282 | PDF_HYPERLINKS = YES |
| 1283 | |
| 1284 | # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of |
| 1285 | # plain latex in the generated Makefile. Set this option to YES to get a |
| 1286 | # higher quality PDF documentation. |
| 1287 | |
| 1288 | USE_PDFLATEX = YES |
| 1289 | |
| 1290 | # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. |
| 1291 | # command to the generated LaTeX files. This will instruct LaTeX to keep |
| 1292 | # running if errors occur, instead of asking the user for help. |
| 1293 | # This option is also used when generating formulas in HTML. |
| 1294 | |
| 1295 | LATEX_BATCHMODE = NO |
| 1296 | |
| 1297 | # If LATEX_HIDE_INDICES is set to YES then doxygen will not |
| 1298 | # include the index chapters (such as File Index, Compound Index, etc.) |
| 1299 | # in the output. |
| 1300 | |
| 1301 | LATEX_HIDE_INDICES = NO |
| 1302 | |
| 1303 | # If LATEX_SOURCE_CODE is set to YES then doxygen will include |
| 1304 | # source code with syntax highlighting in the LaTeX output. |
| 1305 | # Note that which sources are shown also depends on other settings |
| 1306 | # such as SOURCE_BROWSER. |
| 1307 | |
| 1308 | LATEX_SOURCE_CODE = NO |
| 1309 | |
| 1310 | # The LATEX_BIB_STYLE tag can be used to specify the style to use for the |
| 1311 | # bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See |
| 1312 | # http://en.wikipedia.org/wiki/BibTeX for more info. |
| 1313 | |
| 1314 | LATEX_BIB_STYLE = plain |
| 1315 | |
| 1316 | #--------------------------------------------------------------------------- |
| 1317 | # configuration options related to the RTF output |
| 1318 | #--------------------------------------------------------------------------- |
| 1319 | |
| 1320 | # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output |
| 1321 | # The RTF output is optimized for Word 97 and may not look very pretty with |
| 1322 | # other RTF readers or editors. |
| 1323 | |
| 1324 | GENERATE_RTF = NO |
| 1325 | |
| 1326 | # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. |
| 1327 | # If a relative path is entered the value of OUTPUT_DIRECTORY will be |
| 1328 | # put in front of it. If left blank `rtf' will be used as the default path. |
| 1329 | |
| 1330 | RTF_OUTPUT = rtf |
| 1331 | |
| 1332 | # If the COMPACT_RTF tag is set to YES Doxygen generates more compact |
| 1333 | # RTF documents. This may be useful for small projects and may help to |
| 1334 | # save some trees in general. |
| 1335 | |
| 1336 | COMPACT_RTF = NO |
| 1337 | |
| 1338 | # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated |
| 1339 | # will contain hyperlink fields. The RTF file will |
| 1340 | # contain links (just like the HTML output) instead of page references. |
| 1341 | # This makes the output suitable for online browsing using WORD or other |
| 1342 | # programs which support those fields. |
| 1343 | # Note: wordpad (write) and others do not support links. |
| 1344 | |
| 1345 | RTF_HYPERLINKS = NO |
| 1346 | |
| 1347 | # Load style sheet definitions from file. Syntax is similar to doxygen's |
| 1348 | # config file, i.e. a series of assignments. You only have to provide |
| 1349 | # replacements, missing definitions are set to their default value. |
| 1350 | |
| 1351 | RTF_STYLESHEET_FILE = |
| 1352 | |
| 1353 | # Set optional variables used in the generation of an rtf document. |
| 1354 | # Syntax is similar to doxygen's config file. |
| 1355 | |
| 1356 | RTF_EXTENSIONS_FILE = |
| 1357 | |
| 1358 | #--------------------------------------------------------------------------- |
| 1359 | # configuration options related to the man page output |
| 1360 | #--------------------------------------------------------------------------- |
| 1361 | |
| 1362 | # If the GENERATE_MAN tag is set to YES (the default) Doxygen will |
| 1363 | # generate man pages |
| 1364 | |
| 1365 | GENERATE_MAN = NO |
| 1366 | |
| 1367 | # The MAN_OUTPUT tag is used to specify where the man pages will be put. |
| 1368 | # If a relative path is entered the value of OUTPUT_DIRECTORY will be |
| 1369 | # put in front of it. If left blank `man' will be used as the default path. |
| 1370 | |
| 1371 | MAN_OUTPUT = man |
| 1372 | |
| 1373 | # The MAN_EXTENSION tag determines the extension that is added to |
| 1374 | # the generated man pages (default is the subroutine's section .3) |
| 1375 | |
| 1376 | MAN_EXTENSION = .3 |
| 1377 | |
| 1378 | # If the MAN_LINKS tag is set to YES and Doxygen generates man output, |
| 1379 | # then it will generate one additional man file for each entity |
| 1380 | # documented in the real man page(s). These additional files |
| 1381 | # only source the real man page, but without them the man command |
| 1382 | # would be unable to find the correct page. The default is NO. |
| 1383 | |
| 1384 | MAN_LINKS = NO |
| 1385 | |
| 1386 | #--------------------------------------------------------------------------- |
| 1387 | # configuration options related to the XML output |
| 1388 | #--------------------------------------------------------------------------- |
| 1389 | |
| 1390 | # If the GENERATE_XML tag is set to YES Doxygen will |
| 1391 | # generate an XML file that captures the structure of |
| 1392 | # the code including all documentation. |
| 1393 | |
| 1394 | GENERATE_XML = NO |
| 1395 | |
| 1396 | # The XML_OUTPUT tag is used to specify where the XML pages will be put. |
| 1397 | # If a relative path is entered the value of OUTPUT_DIRECTORY will be |
| 1398 | # put in front of it. If left blank `xml' will be used as the default path. |
| 1399 | |
| 1400 | XML_OUTPUT = xml |
| 1401 | |
| 1402 | # The XML_SCHEMA tag can be used to specify an XML schema, |
| 1403 | # which can be used by a validating XML parser to check the |
| 1404 | # syntax of the XML files. |
| 1405 | |
| 1406 | XML_SCHEMA = |
| 1407 | |
| 1408 | # The XML_DTD tag can be used to specify an XML DTD, |
| 1409 | # which can be used by a validating XML parser to check the |
| 1410 | # syntax of the XML files. |
| 1411 | |
| 1412 | XML_DTD = |
| 1413 | |
| 1414 | # If the XML_PROGRAMLISTING tag is set to YES Doxygen will |
| 1415 | # dump the program listings (including syntax highlighting |
| 1416 | # and cross-referencing information) to the XML output. Note that |
| 1417 | # enabling this will significantly increase the size of the XML output. |
| 1418 | |
| 1419 | XML_PROGRAMLISTING = YES |
| 1420 | |
| 1421 | #--------------------------------------------------------------------------- |
| 1422 | # configuration options for the AutoGen Definitions output |
| 1423 | #--------------------------------------------------------------------------- |
| 1424 | |
| 1425 | # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will |
| 1426 | # generate an AutoGen Definitions (see autogen.sf.net) file |
| 1427 | # that captures the structure of the code including all |
| 1428 | # documentation. Note that this feature is still experimental |
| 1429 | # and incomplete at the moment. |
| 1430 | |
| 1431 | GENERATE_AUTOGEN_DEF = NO |
| 1432 | |
| 1433 | #--------------------------------------------------------------------------- |
| 1434 | # configuration options related to the Perl module output |
| 1435 | #--------------------------------------------------------------------------- |
| 1436 | |
| 1437 | # If the GENERATE_PERLMOD tag is set to YES Doxygen will |
| 1438 | # generate a Perl module file that captures the structure of |
| 1439 | # the code including all documentation. Note that this |
| 1440 | # feature is still experimental and incomplete at the |
| 1441 | # moment. |
| 1442 | |
| 1443 | GENERATE_PERLMOD = NO |
| 1444 | |
| 1445 | # If the PERLMOD_LATEX tag is set to YES Doxygen will generate |
| 1446 | # the necessary Makefile rules, Perl scripts and LaTeX code to be able |
| 1447 | # to generate PDF and DVI output from the Perl module output. |
| 1448 | |
| 1449 | PERLMOD_LATEX = NO |
| 1450 | |
| 1451 | # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be |
| 1452 | # nicely formatted so it can be parsed by a human reader. |
| 1453 | # This is useful |
| 1454 | # if you want to understand what is going on. |
| 1455 | # On the other hand, if this |
| 1456 | # tag is set to NO the size of the Perl module output will be much smaller |
| 1457 | # and Perl will parse it just the same. |
| 1458 | |
| 1459 | PERLMOD_PRETTY = YES |
| 1460 | |
| 1461 | # The names of the make variables in the generated doxyrules.make file |
| 1462 | # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. |
| 1463 | # This is useful so different doxyrules.make files included by the same |
| 1464 | # Makefile don't overwrite each other's variables. |
| 1465 | |
| 1466 | PERLMOD_MAKEVAR_PREFIX = |
| 1467 | |
| 1468 | #--------------------------------------------------------------------------- |
| 1469 | # Configuration options related to the preprocessor |
| 1470 | #--------------------------------------------------------------------------- |
| 1471 | |
| 1472 | # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will |
| 1473 | # evaluate all C-preprocessor directives found in the sources and include |
| 1474 | # files. |
| 1475 | |
| 1476 | ENABLE_PREPROCESSING = YES |
| 1477 | |
| 1478 | # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro |
| 1479 | # names in the source code. If set to NO (the default) only conditional |
| 1480 | # compilation will be performed. Macro expansion can be done in a controlled |
| 1481 | # way by setting EXPAND_ONLY_PREDEF to YES. |
| 1482 | |
| 1483 | MACRO_EXPANSION = NO |
| 1484 | |
| 1485 | # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES |
| 1486 | # then the macro expansion is limited to the macros specified with the |
| 1487 | # PREDEFINED and EXPAND_AS_DEFINED tags. |
| 1488 | |
| 1489 | EXPAND_ONLY_PREDEF = NO |
| 1490 | |
| 1491 | # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files |
| 1492 | # pointed to by INCLUDE_PATH will be searched when a #include is found. |
| 1493 | |
| 1494 | SEARCH_INCLUDES = NO |
| 1495 | |
| 1496 | # The INCLUDE_PATH tag can be used to specify one or more directories that |
| 1497 | # contain include files that are not input files but should be processed by |
| 1498 | # the preprocessor. |
| 1499 | |
| 1500 | INCLUDE_PATH = |
| 1501 | |
| 1502 | # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard |
| 1503 | # patterns (like *.h and *.hpp) to filter out the header-files in the |
| 1504 | # directories. If left blank, the patterns specified with FILE_PATTERNS will |
| 1505 | # be used. |
| 1506 | |
| 1507 | INCLUDE_FILE_PATTERNS = |
| 1508 | |
| 1509 | # The PREDEFINED tag can be used to specify one or more macro names that |
| 1510 | # are defined before the preprocessor is started (similar to the -D option of |
| 1511 | # gcc). The argument of the tag is a list of macros of the form: name |
| 1512 | # or name=definition (no spaces). If the definition and the = are |
| 1513 | # omitted =1 is assumed. To prevent a macro definition from being |
| 1514 | # undefined via #undef or recursively expanded use the := operator |
| 1515 | # instead of the = operator. |
| 1516 | |
| 1517 | PREDEFINED = WIN32 \ |
| 1518 | = \ |
| 1519 | 1 |
| 1520 | |
| 1521 | # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then |
| 1522 | # this tag can be used to specify a list of macro names that should be expanded. |
| 1523 | # The macro definition that is found in the sources will be used. |
| 1524 | # Use the PREDEFINED tag if you want to use a different macro definition that |
| 1525 | # overrules the definition found in the source code. |
| 1526 | |
| 1527 | EXPAND_AS_DEFINED = |
| 1528 | |
| 1529 | # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then |
| 1530 | # doxygen's preprocessor will remove all references to function-like macros |
| 1531 | # that are alone on a line, have an all uppercase name, and do not end with a |
| 1532 | # semicolon, because these will confuse the parser if not removed. |
| 1533 | |
| 1534 | SKIP_FUNCTION_MACROS = YES |
| 1535 | |
| 1536 | #--------------------------------------------------------------------------- |
| 1537 | # Configuration::additions related to external references |
| 1538 | #--------------------------------------------------------------------------- |
| 1539 | |
| 1540 | # The TAGFILES option can be used to specify one or more tagfiles. For each |
| 1541 | # tag file the location of the external documentation should be added. The |
| 1542 | # format of a tag file without this location is as follows: |
| 1543 | # |
| 1544 | # TAGFILES = file1 file2 ... |
| 1545 | # Adding location for the tag files is done as follows: |
| 1546 | # |
| 1547 | # TAGFILES = file1=loc1 "file2 = loc2" ... |
| 1548 | # where "loc1" and "loc2" can be relative or absolute paths |
| 1549 | # or URLs. Note that each tag file must have a unique name (where the name does |
| 1550 | # NOT include the path). If a tag file is not located in the directory in which |
| 1551 | # doxygen is run, you must also specify the path to the tagfile here. |
| 1552 | |
| 1553 | TAGFILES = |
| 1554 | |
| 1555 | # When a file name is specified after GENERATE_TAGFILE, doxygen will create |
| 1556 | # a tag file that is based on the input files it reads. |
| 1557 | |
| 1558 | GENERATE_TAGFILE = |
| 1559 | |
| 1560 | # If the ALLEXTERNALS tag is set to YES all external classes will be listed |
| 1561 | # in the class index. If set to NO only the inherited external classes |
| 1562 | # will be listed. |
| 1563 | |
| 1564 | ALLEXTERNALS = NO |
| 1565 | |
| 1566 | # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed |
| 1567 | # in the modules index. If set to NO, only the current project's groups will |
| 1568 | # be listed. |
| 1569 | |
| 1570 | EXTERNAL_GROUPS = YES |
| 1571 | |
| 1572 | # The PERL_PATH should be the absolute path and name of the perl script |
| 1573 | # interpreter (i.e. the result of `which perl'). |
| 1574 | |
| 1575 | PERL_PATH = /bin/perl |
| 1576 | |
| 1577 | #--------------------------------------------------------------------------- |
| 1578 | # Configuration options related to the dot tool |
| 1579 | #--------------------------------------------------------------------------- |
| 1580 | |
| 1581 | # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will |
| 1582 | # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base |
| 1583 | # or super classes. Setting the tag to NO turns the diagrams off. Note that |
| 1584 | # this option also works with HAVE_DOT disabled, but it is recommended to |
| 1585 | # install and use dot, since it yields more powerful graphs. |
| 1586 | |
| 1587 | CLASS_DIAGRAMS = NO |
| 1588 | |
| 1589 | # You can define message sequence charts within doxygen comments using the \msc |
| 1590 | # command. Doxygen will then run the mscgen tool (see |
| 1591 | # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the |
| 1592 | # documentation. The MSCGEN_PATH tag allows you to specify the directory where |
| 1593 | # the mscgen tool resides. If left empty the tool is assumed to be found in the |
| 1594 | # default search path. |
| 1595 | |
| 1596 | MSCGEN_PATH = |
| 1597 | |
| 1598 | # If set to YES, the inheritance and collaboration graphs will hide |
| 1599 | # inheritance and usage relations if the target is undocumented |
| 1600 | # or is not a class. |
| 1601 | |
| 1602 | HIDE_UNDOC_RELATIONS = YES |
| 1603 | |
| 1604 | # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is |
| 1605 | # available from the path. This tool is part of Graphviz, a graph visualization |
| 1606 | # toolkit from AT&T and Lucent Bell Labs. The other options in this section |
| 1607 | # have no effect if this option is set to NO (the default) |
| 1608 | |
| 1609 | HAVE_DOT = NO |
| 1610 | |
| 1611 | # The DOT_NUM_THREADS specifies the number of dot invocations doxygen is |
| 1612 | # allowed to run in parallel. When set to 0 (the default) doxygen will |
| 1613 | # base this on the number of processors available in the system. You can set it |
| 1614 | # explicitly to a value larger than 0 to get control over the balance |
| 1615 | # between CPU load and processing speed. |
| 1616 | |
| 1617 | DOT_NUM_THREADS = 0 |
| 1618 | |
| 1619 | # By default doxygen will use the Helvetica font for all dot files that |
| 1620 | # doxygen generates. When you want a differently looking font you can specify |
| 1621 | # the font name using DOT_FONTNAME. You need to make sure dot is able to find |
| 1622 | # the font, which can be done by putting it in a standard location or by setting |
| 1623 | # the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the |
| 1624 | # directory containing the font. |
| 1625 | |
| 1626 | DOT_FONTNAME = Helvetica |
| 1627 | |
| 1628 | # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. |
| 1629 | # The default size is 10pt. |
| 1630 | |
| 1631 | DOT_FONTSIZE = 10 |
| 1632 | |
| 1633 | # By default doxygen will tell dot to use the Helvetica font. |
| 1634 | # If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to |
| 1635 | # set the path where dot can find it. |
| 1636 | |
| 1637 | DOT_FONTPATH = |
| 1638 | |
| 1639 | # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen |
| 1640 | # will generate a graph for each documented class showing the direct and |
| 1641 | # indirect inheritance relations. Setting this tag to YES will force the |
| 1642 | # CLASS_DIAGRAMS tag to NO. |
| 1643 | |
| 1644 | CLASS_GRAPH = YES |
| 1645 | |
| 1646 | # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen |
| 1647 | # will generate a graph for each documented class showing the direct and |
| 1648 | # indirect implementation dependencies (inheritance, containment, and |
| 1649 | # class references variables) of the class with other documented classes. |
| 1650 | |
| 1651 | COLLABORATION_GRAPH = YES |
| 1652 | |
| 1653 | # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen |
| 1654 | # will generate a graph for groups, showing the direct groups dependencies |
| 1655 | |
| 1656 | GROUP_GRAPHS = YES |
| 1657 | |
| 1658 | # If the UML_LOOK tag is set to YES doxygen will generate inheritance and |
| 1659 | # collaboration diagrams in a style similar to the OMG's Unified Modeling |
| 1660 | # Language. |
| 1661 | |
| 1662 | UML_LOOK = NO |
| 1663 | |
| 1664 | # If the UML_LOOK tag is enabled, the fields and methods are shown inside |
| 1665 | # the class node. If there are many fields or methods and many nodes the |
| 1666 | # graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS |
| 1667 | # threshold limits the number of items for each type to make the size more |
| 1668 | # managable. Set this to 0 for no limit. Note that the threshold may be |
| 1669 | # exceeded by 50% before the limit is enforced. |
| 1670 | |
| 1671 | UML_LIMIT_NUM_FIELDS = 10 |
| 1672 | |
| 1673 | # If set to YES, the inheritance and collaboration graphs will show the |
| 1674 | # relations between templates and their instances. |
| 1675 | |
| 1676 | TEMPLATE_RELATIONS = NO |
| 1677 | |
| 1678 | # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT |
| 1679 | # tags are set to YES then doxygen will generate a graph for each documented |
| 1680 | # file showing the direct and indirect include dependencies of the file with |
| 1681 | # other documented files. |
| 1682 | |
| 1683 | INCLUDE_GRAPH = YES |
| 1684 | |
| 1685 | # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and |
| 1686 | # HAVE_DOT tags are set to YES then doxygen will generate a graph for each |
| 1687 | # documented header file showing the documented files that directly or |
| 1688 | # indirectly include this file. |
| 1689 | |
| 1690 | INCLUDED_BY_GRAPH = YES |
| 1691 | |
| 1692 | # If the CALL_GRAPH and HAVE_DOT options are set to YES then |
| 1693 | # doxygen will generate a call dependency graph for every global function |
| 1694 | # or class method. Note that enabling this option will significantly increase |
| 1695 | # the time of a run. So in most cases it will be better to enable call graphs |
| 1696 | # for selected functions only using the \callgraph command. |
| 1697 | |
| 1698 | CALL_GRAPH = NO |
| 1699 | |
| 1700 | # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then |
| 1701 | # doxygen will generate a caller dependency graph for every global function |
| 1702 | # or class method. Note that enabling this option will significantly increase |
| 1703 | # the time of a run. So in most cases it will be better to enable caller |
| 1704 | # graphs for selected functions only using the \callergraph command. |
| 1705 | |
| 1706 | CALLER_GRAPH = NO |
| 1707 | |
| 1708 | # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen |
| 1709 | # will generate a graphical hierarchy of all classes instead of a textual one. |
| 1710 | |
| 1711 | GRAPHICAL_HIERARCHY = YES |
| 1712 | |
| 1713 | # If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES |
| 1714 | # then doxygen will show the dependencies a directory has on other directories |
| 1715 | # in a graphical way. The dependency relations are determined by the #include |
| 1716 | # relations between the files in the directories. |
| 1717 | |
| 1718 | DIRECTORY_GRAPH = YES |
| 1719 | |
| 1720 | # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images |
| 1721 | # generated by dot. Possible values are svg, png, jpg, or gif. |
| 1722 | # If left blank png will be used. If you choose svg you need to set |
| 1723 | # HTML_FILE_EXTENSION to xhtml in order to make the SVG files |
| 1724 | # visible in IE 9+ (other browsers do not have this requirement). |
| 1725 | |
| 1726 | DOT_IMAGE_FORMAT = png |
| 1727 | |
| 1728 | # If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to |
| 1729 | # enable generation of interactive SVG images that allow zooming and panning. |
| 1730 | # Note that this requires a modern browser other than Internet Explorer. |
| 1731 | # Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you |
| 1732 | # need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files |
| 1733 | # visible. Older versions of IE do not have SVG support. |
| 1734 | |
| 1735 | INTERACTIVE_SVG = NO |
| 1736 | |
| 1737 | # The tag DOT_PATH can be used to specify the path where the dot tool can be |
| 1738 | # found. If left blank, it is assumed the dot tool can be found in the path. |
| 1739 | |
| 1740 | DOT_PATH = |
| 1741 | |
| 1742 | # The DOTFILE_DIRS tag can be used to specify one or more directories that |
| 1743 | # contain dot files that are included in the documentation (see the |
| 1744 | # \dotfile command). |
| 1745 | |
| 1746 | DOTFILE_DIRS = |
| 1747 | |
| 1748 | # The MSCFILE_DIRS tag can be used to specify one or more directories that |
| 1749 | # contain msc files that are included in the documentation (see the |
| 1750 | # \mscfile command). |
| 1751 | |
| 1752 | MSCFILE_DIRS = |
| 1753 | |
| 1754 | # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of |
| 1755 | # nodes that will be shown in the graph. If the number of nodes in a graph |
| 1756 | # becomes larger than this value, doxygen will truncate the graph, which is |
| 1757 | # visualized by representing a node as a red box. Note that doxygen if the |
| 1758 | # number of direct children of the root node in a graph is already larger than |
| 1759 | # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note |
| 1760 | # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. |
| 1761 | |
| 1762 | DOT_GRAPH_MAX_NODES = 50 |
| 1763 | |
| 1764 | # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the |
| 1765 | # graphs generated by dot. A depth value of 3 means that only nodes reachable |
| 1766 | # from the root by following a path via at most 3 edges will be shown. Nodes |
| 1767 | # that lay further from the root node will be omitted. Note that setting this |
| 1768 | # option to 1 or 2 may greatly reduce the computation time needed for large |
| 1769 | # code bases. Also note that the size of a graph can be further restricted by |
| 1770 | # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. |
| 1771 | |
| 1772 | MAX_DOT_GRAPH_DEPTH = 0 |
| 1773 | |
| 1774 | # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent |
| 1775 | # background. This is disabled by default, because dot on Windows does not |
| 1776 | # seem to support this out of the box. Warning: Depending on the platform used, |
| 1777 | # enabling this option may lead to badly anti-aliased labels on the edges of |
| 1778 | # a graph (i.e. they become hard to read). |
| 1779 | |
| 1780 | DOT_TRANSPARENT = NO |
| 1781 | |
| 1782 | # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output |
| 1783 | # files in one run (i.e. multiple -o and -T options on the command line). This |
| 1784 | # makes dot run faster, but since only newer versions of dot (>1.8.10) |
| 1785 | # support this, this feature is disabled by default. |
| 1786 | |
| 1787 | DOT_MULTI_TARGETS = NO |
| 1788 | |
| 1789 | # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will |
| 1790 | # generate a legend page explaining the meaning of the various boxes and |
| 1791 | # arrows in the dot generated graphs. |
| 1792 | |
| 1793 | GENERATE_LEGEND = YES |
| 1794 | |
| 1795 | # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will |
| 1796 | # remove the intermediate dot files that are used to generate |
| 1797 | # the various graphs. |
| 1798 | |
| 1799 | DOT_CLEANUP = YES |
trunk/3rdparty/luabridge/Manual.html
| r0 | r242832 | |
| 1 | <!doctype html> |
| 2 | <html> |
| 3 | <head> |
| 4 | <title>LuaBridge 2.0 Reference Manual</title> |
| 5 | <META HTTP-EQUIV="content-type" CONTENT="text/html; charset=iso-8859-1"> |
| 6 | |
| 7 | <!--=========================================================================--> |
| 8 | <style TYPE="text/css"> |
| 9 | |
| 10 | body { |
| 11 | color: #000000 ; |
| 12 | background-color: #FFFFFF ; |
| 13 | font-family: Helvetica, Arial, sans-serif ; |
| 14 | text-align: justify ; |
| 15 | margin-right: 30px ; |
| 16 | margin-left: 30px ; |
| 17 | } |
| 18 | |
| 19 | h1, h2, h3, h4 { |
| 20 | font-family: Verdana, Geneva, sans-serif ; |
| 21 | font-weight: normal ; |
| 22 | font-style: normal ; |
| 23 | } |
| 24 | |
| 25 | h1 { |
| 26 | padding-top: 0.4em ; |
| 27 | padding-bottom: 0.4em ; |
| 28 | padding-left: 24px ; |
| 29 | margin-left: -24px ; |
| 30 | background-color: #ffe668 ; |
| 31 | border-radius: 8px ; |
| 32 | } |
| 33 | |
| 34 | h2 { |
| 35 | padding-top: 0.4em ; |
| 36 | padding-bottom: 0.4em ; |
| 37 | padding-left: 1em ; |
| 38 | padding-right: 1em ; |
| 39 | background-color: #ffe668 ; |
| 40 | border-radius: 8px ; |
| 41 | } |
| 42 | |
| 43 | h3 { |
| 44 | padding-left: 0.5em ; |
| 45 | border-left: solid #ffe668 1em ; |
| 46 | } |
| 47 | |
| 48 | a:link { |
| 49 | color: #8d5c00 ; |
| 50 | background-color: inherit ; |
| 51 | text-decoration: none ; |
| 52 | } |
| 53 | |
| 54 | a:visited { |
| 55 | color: #b17b26; |
| 56 | background-color: inherit ; |
| 57 | text-decoration: none ; |
| 58 | } |
| 59 | |
| 60 | a:link:hover, a:visited:hover { |
| 61 | color: #8d5c00 ; |
| 62 | background-color: #ffe668 ; |
| 63 | } |
| 64 | |
| 65 | a:link:active, a:visited:active { |
| 66 | color: inherit; |
| 67 | } |
| 68 | |
| 69 | hr { |
| 70 | border: 0 ; |
| 71 | height: 1px ; |
| 72 | color: #a0a0a0 ; |
| 73 | background-color: #a0a0a0 ; |
| 74 | } |
| 75 | |
| 76 | :target { |
| 77 | background-color: #F8F8F8 ; |
| 78 | padding-top: 2px ; |
| 79 | padding-bottom: 2px ; |
| 80 | padding-left: 8px; |
| 81 | padding-right: 8px; |
| 82 | border: solid #a0a0a0 2px ; |
| 83 | } |
| 84 | |
| 85 | .footer { |
| 86 | color: gray ; |
| 87 | font-size: small ; |
| 88 | } |
| 89 | |
| 90 | ul { |
| 91 | list-style-type: none ; |
| 92 | list-style-position: outside ; |
| 93 | } |
| 94 | |
| 95 | ul.bullets { |
| 96 | list-style-type: disc ; |
| 97 | } |
| 98 | |
| 99 | img { |
| 100 | border: 0; |
| 101 | } |
| 102 | |
| 103 | table { |
| 104 | margin-left: 2em; |
| 105 | } |
| 106 | |
| 107 | pre, code { |
| 108 | font-size: 12pt ; |
| 109 | } |
| 110 | |
| 111 | pre { |
| 112 | margin-left: 2em; |
| 113 | } |
| 114 | |
| 115 | pre.split { |
| 116 | padding-left: 2em; |
| 117 | display: table-cell ; |
| 118 | white-space: pre-wrap ; |
| 119 | vertical-align: text-top ; |
| 120 | padding-right: 2em; |
| 121 | } |
| 122 | |
| 123 | pre.split + pre.split { |
| 124 | border-left: 1px solid #ccc; |
| 125 | } |
| 126 | |
| 127 | </style> |
| 128 | |
| 129 | </head> |
| 130 | |
| 131 | <!--=========================================================================--> |
| 132 | |
| 133 | <body> |
| 134 | |
| 135 | <header> |
| 136 | <hr> |
| 137 | <h1>LuaBridge 2.0 Reference Manual</h1> |
| 138 | <hr> |
| 139 | </header> |
| 140 | |
| 141 | <small> |
| 142 | Official repository is located at |
| 143 | <a href="https://github.com/vinniefalco/LuaBridge">https://github.com/vinniefalco/LuaBridge</a>. |
| 144 | <br> |
| 145 | Copyright © 2012 Vinnie Falco. Freely available under the terms of the |
| 146 | <A HREF="http://www.opensource.org/licenses/mit-license.html">MIT License</A>. |
| 147 | </small> |
| 148 | |
| 149 | <nav> |
| 150 | <H2>Contents</H2> |
| 151 | <UL id="toc" style="padding: 0"> |
| 152 | <LI><A href="#s1">1 - Introduction</A> |
| 153 | <UL> |
| 154 | <LI><A href="#s1.1">1.1 - Design</A> |
| 155 | <LI><A href="#s1.2">1.2 - Repository</A> |
| 156 | <LI><A href="#s1.3">1.3 - License and Credits</A> |
| 157 | </UL> |
| 158 | <P> |
| 159 | <LI><A href="#s2">2 - Accessing C++ from Lua</A> |
| 160 | <UL> |
| 161 | <LI><A href="#s2.1">2.1 - Namespaces</A> |
| 162 | <LI><A href="#s2.2">2.2 - Data, Properties, Functions, and CFunctions</A> |
| 163 | <LI><A href="#s2.3">2.3 - Class Objects</A> |
| 164 | <LI><A href="#s2.4">2.4 - Property Member Proxies</A> |
| 165 | <LI><A href="#s2.5">2.5 - Constructors</A> |
| 166 | <LI><A href="#s2.6">2.6 - Lua Stack</A> |
| 167 | <LI><A href="#s2.7">2.7 - lua_State</A> |
| 168 | </UL> |
| 169 | <p> |
| 170 | <LI><A href="#s3">3 - Passing Objects</A> |
| 171 | <UL> |
| 172 | <LI><A href="#s3.1">3.1 - C++ Lifetime</A> |
| 173 | <LI><A href="#s3.2">3.2 - Lua Lifetime</A> |
| 174 | <LI><A href="#s3.3">3.3 - Pointers, References, and Pass by Value</A> |
| 175 | <LI><A href="#s3.4">3.4 - Shared Lifetime</A> |
| 176 | <UL> |
| 177 | <LI><A href="#s3.4.1">3.4.1 - Class RefCountedObjectPtr</A> |
| 178 | <LI><A href="#s3.4.2">3.4.2 - Class RefCountedPtr</A> |
| 179 | <LI><A href="#s3.4.3">3.4.3 - User-defined Containers</A> |
| 180 | <LI><A href="#s3.4.4">3.4.4 - Container Constructors</A> |
| 181 | </UL> |
| 182 | <LI><A href="#s3.5">3.5 - Mixing Lifetimes</A> |
| 183 | <LI><A href="#s3.6">3.6 - Convenience Functions</A> |
| 184 | </UL> |
| 185 | <P> |
| 186 | <LI><A href="#s4">4 - Accessing Lua from C++</A> |
| 187 | <UL> |
| 188 | <LI><A href="#s4.1">4.1 - Class LuaRef</A> |
| 189 | <UL> |
| 190 | <LI><A href="#s4.1.1">4.1.1 - Type Conversions</A> |
| 191 | <LI><A href="#s4.1.2">4.1.2 - Visual Studio 2010, 2012</A> |
| 192 | </UL> |
| 193 | <LI><A href="#s4.2">4.2 - Table Proxies</A> |
| 194 | <LI><A href="#s4.3">4.3 - Calling Lua</A> |
| 195 | <UL> |
| 196 | <LI><A href="#s4.3.1">4.3.1 - Class LuaException</A> |
| 197 | </UL> |
| 198 | </uL> |
| 199 | <P> |
| 200 | <LI><A href="#s5">5 - Security</A> |
| 201 | </UL> |
| 202 | </nav> |
| 203 | |
| 204 | <!--========================================================================--> |
| 205 | |
| 206 | <section> |
| 207 | |
| 208 | <h1>1 - <span id="s1">Introduction</span></h1> |
| 209 | |
| 210 | <p> |
| 211 | <a href="https://github.com/vinniefalco/LuaBridge">LuaBridge</a> is a |
| 212 | lightweight and dependency-free library for mapping data, functions, and |
| 213 | classes back and forth between C++ and <a href="http://wwww.lua.org">Lua</a>, |
| 214 | a powerful, fast, lightweight, embeddable scripting language. LuaBridge has |
| 215 | been tested and works with Lua revisions starting from 5.1.5, although it |
| 216 | should work in any version of Lua from 5.1.0 and later. It also works |
| 217 | transparently with <a href="http://luajit.org/">LuaJIT</a>. |
| 218 | </p> |
| 219 | |
| 220 | <p> |
| 221 | LuaBridge offers the following features: |
| 222 | </p> |
| 223 | |
| 224 | <ul class="bullets" title="Features"> |
| 225 | <li><a href="http://www.opensource.org/licenses/mit-license.html">MIT Licensed</a>, no usage restrictions!</li> |
| 226 | <li>Headers-only: No Makefile, no .cpp files, just one <code>#include</code>!</li> |
| 227 | <li>Simple, light, and nothing else needed (like Boost).</li> |
| 228 | <li>No macros, settings, or configuration scripts needed.</li> |
| 229 | <li>Supports different object lifetime management models.</li> |
| 230 | <li>Convenient, type-safe access to the Lua stack.</li> |
| 231 | <li>Automatic function parameter type binding.</li> |
| 232 | <li>Easy access to Lua objects like tables and functions.</li> |
| 233 | <li>Written in a clear and easy to debug style.</li> |
| 234 | <li>Does not require C++11.</li> |
| 235 | </ul> |
| 236 | |
| 237 | <p> |
| 238 | LuaBridge is distributed as a a collection of header files. You simply add |
| 239 | one line, <code>#include "LuaBridge/LuaBridge.h"</code> where you want to |
| 240 | pass functions, classes, and variables back and forth between C++ and Lua. |
| 241 | There are no additional source files, no compilation settings, and no |
| 242 | Makefiles or IDE-specific project files. LuaBridge is easy to integrate. |
| 243 | </p> |
| 244 | |
| 245 | <p> |
| 246 | C++ concepts like variables and classes are made available to Lua through a |
| 247 | process called <em>registration</em>. Because Lua is weakly typed, the resulting |
| 248 | structure is not rigid. The API is based on C++ template metaprogramming. It |
| 249 | contains template code to automatically generate at compile-time the various |
| 250 | Lua C API calls necessary to export your program's classes and functions to |
| 251 | the Lua environment. |
| 252 | </p> |
| 253 | |
| 254 | <p> |
| 255 | To expose Lua objects to C++, a class called <code>LuaRef</code> is provided. |
| 256 | The implementation allows C++ code to access Lua objects such as numbers |
| 257 | or strings, but more importantly to access things like tables and their |
| 258 | values. Using this class makes idioms like calling Lua functions simple |
| 259 | and clean. |
| 260 | </p> |
| 261 | |
| 262 | <!--========================================================================--> |
| 263 | |
| 264 | <section> |
| 265 | |
| 266 | <h2>1.1 - <span id="s1.1">Design</span></h2> |
| 267 | |
| 268 | <p> |
| 269 | LuaBridge tries to be efficient as possible when creating the "glue" that |
| 270 | exposes C++ data and functions to Lua. At the same time, the code was |
| 271 | written with the intention that it is all as simple and clear as possible, |
| 272 | without resorting to obscure C++ idioms, ugly preprocessor macros, or |
| 273 | configuration settings. Furthermore, it is designed to be "header-only", |
| 274 | making it very easy to integrate into your projects. |
| 275 | </p> |
| 276 | |
| 277 | <p> |
| 278 | Because LuaBridge was written with simplicity in mind there are some features |
| 279 | that are not available. Although it comes close to the highest possible |
| 280 | performance, LuaBridge is not quite the fastest, |
| 281 | <a href="http://code.google.com/p/oolua/">OOLua</a> slightly outperforms |
| 282 | LuaBridge in some tests. LuaBridge also does not try to implement every |
| 283 | possible feature, |
| 284 | <a href="http://www.rasterbar.com/products/luabind.html">LuaBind</a> |
| 285 | explores every corner of the C++ language (but it requires Boost). |
| 286 | </p> |
| 287 | |
| 288 | <p> |
| 289 | LuaBridge does not support: |
| 290 | </p> |
| 291 | |
| 292 | <ul class="bullets"> |
| 293 | <li>Enumerated constants |
| 294 | <li>More than 8 parameters on a function or method (although this can be |
| 295 | increased by adding more <code>TypeListValues</code> specializations). |
| 296 | <li>Overloaded functions, methods, or constructors. |
| 297 | <li>Global variables (variables must be wrapped in a named scope). |
| 298 | <li>Automatic conversion between STL container types and Lua tables. |
| 299 | <li>Inheriting Lua classes from C++ classes. |
| 300 | <li>Passing nil to a C++ function that expects a pointer or reference. |
| 301 | <li>Standard containers like <code>std::shared_ptr</code>. |
| 302 | </ul> |
| 303 | |
| 304 | </section> |
| 305 | |
| 306 | <!--========================================================================--> |
| 307 | |
| 308 | <section> |
| 309 | |
| 310 | <h2>1.2 - <span id="s1.2">Repository</span></h2> |
| 311 | |
| 312 | <p> |
| 313 | The official repository is located at |
| 314 | <a href="https://github.com/vinniefalco/LuaBridge">https://github.com/vinniefalco/LuaBridge</a>. |
| 315 | The branches are organized as follows: |
| 316 | </p> |
| 317 | |
| 318 | <table> |
| 319 | <tr> |
| 320 | <td><b>master</b></td> |
| 321 | <td>Tagged, stable release versions.</td> |
| 322 | </tr> |
| 323 | <tr> |
| 324 | <td><b>release</b></td> |
| 325 | <td>A temporarily created branch that holds a release candidate for review.</td> |
| 326 | </tr> |
| 327 | <tr> |
| 328 | <td><b>develop</b></td> |
| 329 | <td>Contains work in progress, possibly unfinished or with bugs.</td> |
| 330 | </tr> |
| 331 | </table> |
| 332 | |
| 333 | <p> |
| 334 | These repositories are also available: |
| 335 | </p> |
| 336 | |
| 337 | <table> |
| 338 | <tr> |
| 339 | <td><b><a href="https://github.com/vinniefalco/LuaBridgeUnitTests">LuaBridgeUnitTests</a></b></td> |
| 340 | <td>A stand alone command line application to exercise LuaBridge functionality.</td> |
| 341 | </tr> |
| 342 | <tr> |
| 343 | <td><b><a href="https://github.com/vinniefalco/LuaBridgeDemo">LuaBridgeUnitDemo</a></b></td> |
| 344 | <td>A stand alone GUI application that provides an interactive console.</td> |
| 345 | </tr> |
| 346 | </table> |
| 347 | |
| 348 | </section> |
| 349 | |
| 350 | <!--========================================================================--> |
| 351 | |
| 352 | <section> |
| 353 | |
| 354 | <h2>1.3 - <span id="s1.3">License and Credits</span></h2> |
| 355 | |
| 356 | <p> |
| 357 | LuaBridge is published under the terms of the |
| 358 | <a href="http://www.opensource.org/licenses/mit-license.html">MIT License</a>: |
| 359 | </p> |
| 360 | |
| 361 | <pre> |
| 362 | Permission is hereby granted, free of charge, to any person obtaining a copy |
| 363 | of this software and associated documentation files (the "Software"), to deal |
| 364 | in the Software without restriction, including without limitation the rights |
| 365 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| 366 | copies of the Software, and to permit persons to whom the Software is |
| 367 | furnished to do so, subject to the following conditions: |
| 368 | |
| 369 | The above copyright notice and this permission notice shall be included in |
| 370 | all copies or substantial portions of the Software. |
| 371 | |
| 372 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 373 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 374 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| 375 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| 376 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| 377 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| 378 | SOFTWARE. |
| 379 | </pre> |
| 380 | |
| 381 | <p> |
| 382 | The original version of LuaBridge was written by Nathan Reed. The project |
| 383 | has been taken over by Vinnie Falco, who added new functionality and wrote |
| 384 | the new documentation. Vinnie also incorporated <code>LuaRef</code> and |
| 385 | other Lua to C++ binding contributions from Nigel Atkinson. |
| 386 | </p> |
| 387 | |
| 388 | <p> |
| 389 | For questions, comments, or bug reports feel free to open a Github issue |
| 390 | or contact Vinnie Falco directly at the email address indicated below. |
| 391 | </p> |
| 392 | |
| 393 | <ul> |
| 394 | <li>Copyright 2012, Vinnie Falco <a href="mailto:vinnie.falco@gmail.com"><vinnie.falco@gmail.com></a> |
| 395 | <li>Copyright 2008, Nigel Atkinson <a href="mailto:suprapilot+LuaCode@gmail.com"><suprapilot+LuaCode@gmail.com></a> |
| 396 | <li>Copyright 2007, Nathan Reed |
| 397 | <li>Portions from The Loki Library: Copyright 2001 by Andrei Alexandrescu |
| 398 | </ul> |
| 399 | |
| 400 | <p> |
| 401 | Older versions of LuaBridge up to and including 0.2 (available separately) are |
| 402 | distributed under the BSD 3-Clause License. See the corresponding license file |
| 403 | in those versions (distributed separately) for more details. |
| 404 | </p> |
| 405 | |
| 406 | </section> |
| 407 | |
| 408 | <!--========================================================================--> |
| 409 | |
| 410 | </section> |
| 411 | |
| 412 | <section> |
| 413 | |
| 414 | <h1>2 - <span id="s2">Accessing C++ from Lua</span></h1> |
| 415 | |
| 416 | <p> |
| 417 | In order to expose C++ data and functions to Lua, each piece of exported |
| 418 | information must be <em>registered</em>. There are five types of objects that |
| 419 | LuaBridge can register: |
| 420 | </p> |
| 421 | |
| 422 | <table> |
| 423 | <tr> |
| 424 | <td><b>Namespaces</b> </td> |
| 425 | <td>A Lua table that contains other registrations.</td> |
| 426 | </tr> |
| 427 | <tr> |
| 428 | <td><b>Data</b> </td> |
| 429 | <td>Global or static variables, data members, and static data members.</td> |
| 430 | </tr> |
| 431 | <tr> |
| 432 | <td><b>Functions </b></td> |
| 433 | <td>Regular functions, member functions, and static member functions.</td> |
| 434 | </tr> |
| 435 | <tr> |
| 436 | <td><b>CFunctions </b></td> |
| 437 | <td>A regular function, member function, or static member function that |
| 438 | uses the <code>lua_CFunction</code> calling convention.</td> |
| 439 | </tr> |
| 440 | <tr> |
| 441 | <td><b>Properties </b></td> |
| 442 | <td>Global properties, property members, and static property members. |
| 443 | These appear like data to Lua, but are implemented in C++ using |
| 444 | functions to get and set the values.</td> |
| 445 | </tr> |
| 446 | </table> |
| 447 | |
| 448 | <p> |
| 449 | Both data and properties can be marked as <em>read-only</em> at the time of |
| 450 | registration. This is different from <code>const</code>; the values of these |
| 451 | objects can be modified on the C++ side, but Lua scripts cannot change them. |
| 452 | Code samples that follow are in C++ or Lua, depending on context. For brevity |
| 453 | of exposition code samples in C++ assume the traditional variable |
| 454 | <code>lua_State* L</code> is defined, and that a <code>using namespace luabridge</code> |
| 455 | using-directive is in effect. |
| 456 | </p> |
| 457 | |
| 458 | <!--========================================================================--> |
| 459 | |
| 460 | <section> |
| 461 | |
| 462 | <h2>2.1 - <span id="s2.1">Namespaces</span></h2> |
| 463 | |
| 464 | <p> |
| 465 | All LuaBridge registrations take place in a <em>namespace</em>. When we refer |
| 466 | to a <em>namespace</em> we are always talking about a namespace in the Lua |
| 467 | sense, which is implemented using tables. The namespace need not correspond |
| 468 | to a C++ namespace; in fact no C++ namespaces need to exist at all unless you |
| 469 | want them to. LuaBridge namespaces are visible only to Lua scripts; they are |
| 470 | used as a logical grouping tool. To obtain access to the global namespace |
| 471 | we write: |
| 472 | </p> |
| 473 | |
| 474 | <pre> |
| 475 | getGlobalNamespace (L); |
| 476 | </pre> |
| 477 | |
| 478 | <p> |
| 479 | This returns an object on which further registrations can be performed. The |
| 480 | subsequent registrations will go into the global namespace, a practice which |
| 481 | is not recommended. Instead, we can add our own namespace by writing: |
| 482 | </p> |
| 483 | |
| 484 | <pre> |
| 485 | getGlobalNamespace (L) |
| 486 | .beginNamespace ("test"); |
| 487 | </pre> |
| 488 | |
| 489 | <p> |
| 490 | This creates a table in <code>_G</code> called "test". Since we have not |
| 491 | performed any registrations, this table will be empty except for some |
| 492 | bookkeeping key/value pairs. LuaBridge reserves all identifiers that start |
| 493 | with a double underscore. So <code>__test</code> would be an invalid name |
| 494 | (although LuaBridge will silently accept it). Functions like |
| 495 | <code>beginNamespace</code> return the corresponding object on which we can |
| 496 | make more registrations. Given: |
| 497 | </p> |
| 498 | |
| 499 | <pre> |
| 500 | getGlobalNamespace (L) |
| 501 | .beginNamespace ("test") |
| 502 | .beginNamespace ("detail") |
| 503 | .endNamespace () |
| 504 | .beginNamespace ("utility") |
| 505 | .endNamespace () |
| 506 | .endNamespace (); |
| 507 | </pre> |
| 508 | |
| 509 | <p> |
| 510 | The results are accessible to Lua as <code>test</code>, <code>test.detail</code>, |
| 511 | and <code>test.utility</code>. Here we introduce the <code>endNamespace</code> |
| 512 | function; it returns an object representing the original enclosing namespace. |
| 513 | All LuaBridge functions which create registrations return an object upon which |
| 514 | subsequent registrations can be made, allowing for an unlimited number of |
| 515 | registrations to be chained together using the dot operator. Adding two objects |
| 516 | with the same name, in the same namespace, results in undefined behavior |
| 517 | (although LuaBridge will silently accept it). |
| 518 | </p> |
| 519 | |
| 520 | <p> |
| 521 | A namespace can be re-opened later to add more functions. This lets you split |
| 522 | up the registration between different source files. These are equivalent: |
| 523 | </p> |
| 524 | |
| 525 | <pre> |
| 526 | getGlobalNamespace (L) |
| 527 | .beginNamespace ("test") |
| 528 | .addFunction ("foo", foo) |
| 529 | .endNamespace (); |
| 530 | |
| 531 | getGlobalNamespace (L) |
| 532 | .beginNamespace ("test") |
| 533 | .addFunction ("bar", bar) |
| 534 | .endNamespace (); |
| 535 | </pre> |
| 536 | |
| 537 | <p> |
| 538 | and |
| 539 | </p> |
| 540 | |
| 541 | <pre> |
| 542 | getGlobalNamespace (L) |
| 543 | .beginNamespace ("test") |
| 544 | .addFunction ("foo", foo) |
| 545 | .addFunction ("bar", bar) |
| 546 | .endNamespace (); |
| 547 | </pre> |
| 548 | |
| 549 | </section> |
| 550 | |
| 551 | <!--========================================================================--> |
| 552 | |
| 553 | <section> |
| 554 | |
| 555 | <h2>2.2 - <span id="s2.2">Data, Properties, Functions, and CFunctions</span></h2> |
| 556 | |
| 557 | <p> |
| 558 | These are registered into a namespace using <code>addVariable</code>, |
| 559 | <code>addProperty</code>, <code>addFunction</code>, and <code>addCFunction</code>. |
| 560 | When registered functions are called by scripts, LuaBridge automatically takes |
| 561 | care of the conversion of arguments into the appropriate data type when doing |
| 562 | so is possible. This automated system works for the function's return value, |
| 563 | and up to 8 parameters although more can be added by extending the templates. |
| 564 | Pointers, references, and objects of class type as parameters are treated |
| 565 | specially, and explained later. If we have: |
| 566 | </p> |
| 567 | |
| 568 | <pre> |
| 569 | int globalVar; |
| 570 | static float staticVar; |
| 571 | |
| 572 | std::string stringProperty; |
| 573 | std::string getString () { return stringProperty; } |
| 574 | void setString (std::string s) { stringProperty = s; } |
| 575 | |
| 576 | int foo () { return 42; } |
| 577 | void bar (char const*) { } |
| 578 | int cFunc (lua_State* L) { return 0; } |
| 579 | </pre> |
| 580 | |
| 581 | <p> |
| 582 | These are registered with: |
| 583 | </p> |
| 584 | |
| 585 | <pre> |
| 586 | getGlobalNamespace (L) |
| 587 | .beginNamespace ("test") |
| 588 | .addVariable ("var1", &globalVar) |
| 589 | .addVariable ("var2", &staticVar, false) // read-only |
| 590 | .addProperty ("prop1", getString, setString) |
| 591 | .addProperty ("prop2", getString) // read only |
| 592 | .addFunction ("foo", foo) |
| 593 | .addFunction ("bar", bar) |
| 594 | .addCFunction ("cfunc", cFunc) |
| 595 | .endNamespace (); |
| 596 | </pre> |
| 597 | |
| 598 | <p> |
| 599 | Variables can be marked <em>read-only</em> by passing <code>false</code> in |
| 600 | the second optional parameter. If the parameter is omitted, <em>true</em> is |
| 601 | used making the variable read/write. Properties are marked read-only by |
| 602 | omitting the set function. After the registrations above, the following Lua |
| 603 | identifiers are valid: |
| 604 | </p> |
| 605 | |
| 606 | <pre> |
| 607 | test -- a namespace |
| 608 | test.var1 -- a lua_Number variable |
| 609 | test.var2 -- a read-only lua_Number variable |
| 610 | test.prop1 -- a lua_String property |
| 611 | test.prop2 -- a read-only lua_String property |
| 612 | test.foo -- a function returning a lua_Number |
| 613 | test.bar -- a function taking a lua_String as a parameter |
| 614 | test.cfunc -- a function with a variable argument list and multi-return |
| 615 | </pre> |
| 616 | |
| 617 | <p> |
| 618 | Note that <code>test.prop1</code> and `test.prop2` both refer to the |
| 619 | same value. However, since <code>test.prop2</code> is read-only, assignment |
| 620 | attempts will generate a run-time error. These Lua statements have the stated effects: |
| 621 | </p> |
| 622 | |
| 623 | <pre> |
| 624 | test.var1 = 5 -- okay |
| 625 | test.var2 = 6 -- error: var2 is not writable |
| 626 | test.prop1 = "Hello" -- okay |
| 627 | test.prop1 = 68 -- okay, Lua converts the number to a string. |
| 628 | test.prop2 = "bar" -- error: prop2 is not writable |
| 629 | |
| 630 | test.foo () -- calls foo and discards the return value |
| 631 | test.var1 = foo () -- calls foo and stores the result in var1 |
| 632 | test.bar ("Employee") -- calls bar with a string |
| 633 | test.bar (test) -- error: bar expects a string not a table |
| 634 | </pre> |
| 635 | |
| 636 | <p> |
| 637 | LuaBridge does not support overloaded functions nor is it likely to in the |
| 638 | future. Since Lua is dynamically typed, any system that tries to resolve a set |
| 639 | of parameters passed from a script will face considerable ambiguity when |
| 640 | trying to choose an appropriately matching C++ function signature. |
| 641 | </p> |
| 642 | |
| 643 | </section> |
| 644 | |
| 645 | <!--========================================================================--> |
| 646 | |
| 647 | <section> |
| 648 | |
| 649 | <h2>2.3 - <span id="s2.3">Class Objects</span></h2> |
| 650 | |
| 651 | <p> |
| 652 | A class registration is opened using either <code>beginClass</code> or |
| 653 | <code>deriveClass</code> and ended using <code>endClass</code>. Once |
| 654 | registered, a class can later be re-opened for more registrations using |
| 655 | <code>beginClass</code>. However, <code>deriveClass</code> should only be |
| 656 | used once. To add more registrations to an already registered derived class, |
| 657 | use <code>beginClass</code> on it. These declarations: |
| 658 | </p> |
| 659 | |
| 660 | <pre> |
| 661 | struct A { |
| 662 | static int staticData; |
| 663 | static float staticProperty; |
| 664 | |
| 665 | static float getStaticProperty () { return staticProperty; } |
| 666 | static void setStaticProperty (float f) { staticProperty = f; } |
| 667 | static void staticFunc () { } |
| 668 | |
| 669 | static int staticCFunc () { return 0; } |
| 670 | |
| 671 | std::string dataMember; |
| 672 | |
| 673 | char dataProperty; |
| 674 | char getProperty () const { return dataProperty; } |
| 675 | void setProperty (char v) { dataProperty = v; } |
| 676 | |
| 677 | void func1 () { } |
| 678 | virtual void virtualFunc () { } |
| 679 | |
| 680 | int cfunc (lua_State* L) { return 0; } |
| 681 | }; |
| 682 | |
| 683 | struct B : public A { |
| 684 | double dataMember2; |
| 685 | |
| 686 | void func1 () { } |
| 687 | void func2 () { } |
| 688 | void virtualFunc () { } |
| 689 | }; |
| 690 | |
| 691 | int A::staticData; |
| 692 | float A::staticProperty; |
| 693 | </pre> |
| 694 | |
| 695 | <p> |
| 696 | are registered using: |
| 697 | </p> |
| 698 | |
| 699 | <pre> |
| 700 | getGlobalNamespace (L) |
| 701 | .beginNamespace ("test") |
| 702 | .beginClass <A> ("A") |
| 703 | .addStaticData ("staticData", &A::staticData) |
| 704 | .addStaticProperty ("staticProperty", &A::staticProperty) |
| 705 | .addStaticFunction ("staticFunc", &A::staticFunc) |
| 706 | .addStaticCFunction ("staticCFunc", &A::staticCFunc) |
| 707 | .addData ("data", &A::dataMember) |
| 708 | .addProperty ("prop", &A::getProperty, &A::setProperty) |
| 709 | .addFunction ("func1", &A::func1) |
| 710 | .addFunction ("virtualFunc", &A::virtualFunc) |
| 711 | .addCFunction ("cfunc", &A::cfunc) |
| 712 | .endClass () |
| 713 | .deriveClass <B, A> ("B") |
| 714 | .addData ("data", &B::dataMember2) |
| 715 | .addFunction ("func1", &B::func1) |
| 716 | .addFunction ("func2", &B::func2) |
| 717 | .endClass () |
| 718 | .endNameSpace (); |
| 719 | </pre> |
| 720 | |
| 721 | <p> |
| 722 | Method registration works just like function registration. Virtual methods |
| 723 | work normally; no special syntax is needed. const methods are detected and |
| 724 | const-correctness is enforced, so if a function returns a const object (or |
| 725 | a container holding to a const object) to Lua, that reference to the object |
| 726 | will be considered const and only const methods can be called on it. |
| 727 | Destructors are registered automatically for each class. |
| 728 | </p> |
| 729 | |
| 730 | <p> |
| 731 | As with regular variables and properties, class data and properties can be |
| 732 | marked read-only by passing false in the second parameter, or omitting the set |
| 733 | set function respectively. The `deriveClass` takes two template arguments: the |
| 734 | class to be registered, and its base class. Inherited methods do not have to |
| 735 | be re-declared and will function normally in Lua. If a class has a base class |
| 736 | that is **not** registered with Lua, there is no need to declare it as a |
| 737 | subclass. |
| 738 | </p> |
| 739 | |
| 740 | <p> |
| 741 | Remember that in Lua, the colon operator '<code>:</code>' is used for |
| 742 | method call syntax: |
| 743 | </p> |
| 744 | |
| 745 | <pre> |
| 746 | local a = A () |
| 747 | |
| 748 | a.func1 () -- Does nothing |
| 749 | a:func1 () -- Works |
| 750 | </pre> |
| 751 | |
| 752 | </section> |
| 753 | |
| 754 | <!--========================================================================--> |
| 755 | |
| 756 | <section> |
| 757 | |
| 758 | <h2>2.4 - <span id="s2.4">Property Member Proxies</span></h2> |
| 759 | |
| 760 | <p> |
| 761 | Sometimes when registering a class which comes from a third party library, the |
| 762 | data is not exposed in a way that can be expressed as a pointer to member, |
| 763 | there are no get or set functions, or the get and set functons do not have the |
| 764 | right function signature. Since the class declaration is closed for changes, |
| 765 | LuaBridge allows for a <em>property member proxy</em>. This is a pair of get |
| 766 | and set flat functions which take as their first parameter a pointer to |
| 767 | the object. This is easily understood with the following example: |
| 768 | </p> |
| 769 | |
| 770 | <pre> |
| 771 | // Third party declaration, can't be changed |
| 772 | struct Vec |
| 773 | { |
| 774 | float coord [3]; |
| 775 | }; |
| 776 | </pre> |
| 777 | |
| 778 | <p> |
| 779 | Taking the address of an array element, e.g. <code>&Vec::coord [0]</code> |
| 780 | results in an error instead of a pointer-to-member. The class is closed for |
| 781 | modifications, but we want to export Vec objects to Lua using the familiar |
| 782 | object notation. To do this, first we add a "helper" class: |
| 783 | </p> |
| 784 | |
| 785 | <pre> |
| 786 | struct VecHelper |
| 787 | { |
| 788 | template <unsigned index> |
| 789 | static float get (Vec const* vec) |
| 790 | { |
| 791 | return vec->coord [index]; |
| 792 | } |
| 793 | |
| 794 | template <unsigned index> |
| 795 | static void set (Vec* vec, float value) |
| 796 | { |
| 797 | vec->coord [index] = value; |
| 798 | } |
| 799 | }; |
| 800 | </pre> |
| 801 | |
| 802 | <p> |
| 803 | This helper class is only used to provide property member proxies. |
| 804 | <code>Vec</code> continues to be used in the C++ code as it was before. |
| 805 | Now we can register the <code>Vec</code> class with property member proxies for |
| 806 | <code>x</code>, <code>y</code>, and <code>z</code>: |
| 807 | </p> |
| 808 | |
| 809 | <pre> |
| 810 | getGlobalNamespace (L) |
| 811 | .beginNamespace ("test") |
| 812 | .beginClass <Vec> ("Vec") |
| 813 | .addProperty ("x", &VecHelper::get <0>, &VecHelper::set <0>) |
| 814 | .addProperty ("y", &VecHelper::get <1>, &VecHelper::set <1>) |
| 815 | .addProperty ("z", &VecHelper::get <2>, &VecHelper::set <2>) |
| 816 | .endClass () |
| 817 | .endNamespace (); |
| 818 | </pre> |
| 819 | |
| 820 | </section> |
| 821 | |
| 822 | <!--========================================================================--> |
| 823 | |
| 824 | <section> |
| 825 | |
| 826 | <h2>2.5 - <span id="s2.5">Constructors</span></h2> |
| 827 | |
| 828 | <p> |
| 829 | A single constructor may be added for a class using <code>addConstructor</code>. |
| 830 | LuaBridge cannot automatically determine the number and types of constructor |
| 831 | parameters like it can for functions and methods, so you must provide them. |
| 832 | This is done by specifying the signature of the desired constructor function |
| 833 | as the first template parameter to <code>addConstructor</code>. The parameter |
| 834 | types will be extracted from this (the return type is ignored). For example, |
| 835 | these statements register constructors for the given classes: |
| 836 | </p> |
| 837 | |
| 838 | <pre> |
| 839 | struct A { |
| 840 | A (); |
| 841 | }; |
| 842 | |
| 843 | struct B { |
| 844 | explicit B (char const* s, int nChars); |
| 845 | }; |
| 846 | |
| 847 | getGlobalNamespace (L) |
| 848 | .beginNamespace ("test") |
| 849 | .beginClass <A> ("A") |
| 850 | .addConstructor <void (*) (void)> () |
| 851 | .endClass () |
| 852 | .beginClass <B> ("B") |
| 853 | .addConstructor <void (*) (char const*, int)> () |
| 854 | .endClass () |
| 855 | .endNamespace (); |
| 856 | </pre> |
| 857 | |
| 858 | <p> |
| 859 | Constructors added in this fashion are called from Lua using the fully |
| 860 | qualified name of the class. This Lua code will create instances of |
| 861 | <code>A</code> and <code>B</code>. |
| 862 | </p> |
| 863 | |
| 864 | <pre> |
| 865 | a = test.A () -- Create a new A. |
| 866 | b = test.B ("hello", 5) -- Create a new B. |
| 867 | b = test.B () -- Error: expected string in argument 1 |
| 868 | </pre> |
| 869 | |
| 870 | </section> |
| 871 | |
| 872 | <!--========================================================================--> |
| 873 | |
| 874 | <section> |
| 875 | |
| 876 | <h2>2.6 - <span id="s2.6">Lua Stack</span></h2> |
| 877 | |
| 878 | <p> |
| 879 | In the Lua C API, all operations on the <code>lua_State</code> are performed |
| 880 | through the Lua stack. In order to pass values back and forth between C++ |
| 881 | and Lua, LuaBridge uses specializations of this template class concept: |
| 882 | </p> |
| 883 | |
| 884 | <pre> |
| 885 | template <class T> |
| 886 | struct Stack |
| 887 | { |
| 888 | static void push (lua_State* L, T t); |
| 889 | static T get (lua_State* L, int index); |
| 890 | }; |
| 891 | </pre> |
| 892 | |
| 893 | <p> |
| 894 | When a specialization of <code>Stack</code> exists for a given type |
| 895 | <code>T</code> we say that the <code>T</code> is <em>convertible</em>. |
| 896 | Throughout this document and the LuaBridge API, these types can be used |
| 897 | anywhere a convertible type is expected. |
| 898 | </p> |
| 899 | |
| 900 | <p> |
| 901 | The Stack template class specializations are used automatically for variables, |
| 902 | properties, data members, property members, function arguments and return |
| 903 | values. These basic types are supported: |
| 904 | </p> |
| 905 | |
| 906 | <ul class="bullets"> |
| 907 | <li><code>bool</code> |
| 908 | <li><code>char</code>, converted to a string of length one. |
| 909 | <li><code>char const*</code> and <code>std::string</code> strings. |
| 910 | <li>Integers, <code>float</code>, and <code>double</code>, |
| 911 | converted to <code>Lua_number</code>. |
| 912 | </ul> |
| 913 | |
| 914 | <p> |
| 915 | User-defined types which are convertible to one of the basic types are |
| 916 | possible, simply provide a <code>Stack<></code> specialization in the |
| 917 | <code>luabridge</code> namespace for your user-defined type, modeled after |
| 918 | the existing types. For example, here is a specialization for a |
| 919 | <code>juce::String</code>: |
| 920 | </p> |
| 921 | |
| 922 | <pre> |
| 923 | template <> |
| 924 | struct Stack <juce::String> |
| 925 | { |
| 926 | static void push (lua_State* L, juce::String s) |
| 927 | { |
| 928 | lua_pushstring (L, s.toUTF8 ()); |
| 929 | } |
| 930 | |
| 931 | static juce::String get (lua_State* L, int index) |
| 932 | { |
| 933 | return juce::String (luaL_checkstring (L, index)); |
| 934 | } |
| 935 | }; |
| 936 | </pre> |
| 937 | |
| 938 | </section> |
| 939 | |
| 940 | <!--========================================================================--> |
| 941 | |
| 942 | <section> |
| 943 | |
| 944 | <h2>2.7 - <span id="s2.7">lua_State</span></h2> |
| 945 | |
| 946 | <p> |
| 947 | Sometimes it is convenient from within a bound function or member function |
| 948 | to gain access to the `lua_State*` normally available to a `lua_CFunction`. |
| 949 | With LuaBridge, all you need to do is add a `lua_State*` as the last |
| 950 | parameter of your bound function: |
| 951 | </p> |
| 952 | |
| 953 | <pre> |
| 954 | void useState (lua_State* L); |
| 955 | |
| 956 | getGlobalNamespace (L).addFunction ("useState", &useState); |
| 957 | </pre> |
| 958 | |
| 959 | <p> |
| 960 | You can still include regular arguments while receiving the state: |
| 961 | </p> |
| 962 | |
| 963 | <pre> |
| 964 | void useStateAndArgs (int i, std::string s, lua_State* L); |
| 965 | |
| 966 | getGlobalNamespace (L).addFunction ("useStateAndArgs", &useStateAndArgs); |
| 967 | </pre> |
| 968 | |
| 969 | <p> |
| 970 | When the script calls <code>useStateAndArgs</code>, it passes only the integer |
| 971 | and string parameters. LuaBridge takes care of inserting the <code>lua_State*</code> |
| 972 | into the argument list for the corresponding C++ function. This will work |
| 973 | correctly even for the state created by coroutines. Undefined behavior results |
| 974 | if the <code>lua_State*</code> is not the last parameter. |
| 975 | </p> |
| 976 | |
| 977 | </section> |
| 978 | |
| 979 | <!--========================================================================--> |
| 980 | |
| 981 | </section> |
| 982 | |
| 983 | <section> |
| 984 | |
| 985 | <h1>3 - <span id="s3">Passing Objects</span></h1> |
| 986 | |
| 987 | <p> |
| 988 | An object of a registered class <code>T</code> may be passed to Lua as: |
| 989 | </p> |
| 990 | |
| 991 | <table> |
| 992 | <tr> |
| 993 | <td><b><code>T</code></b></td> |
| 994 | <td>Passed by value (a copy), with <em>Lua lifetime</em>.</td> |
| 995 | </tr> |
| 996 | <tr> |
| 997 | <td><b><code>T const</code></b></td> |
| 998 | <td>Passed by value (a copy), with <em>Lua lifetime</em>.</td> |
| 999 | </tr> |
| 1000 | <tr> |
| 1001 | <td><b><code>T*</code></b></td> |
| 1002 | <td>Passed by reference, with <em>C++ lifetime</em>.</td> |
| 1003 | </tr> |
| 1004 | <tr> |
| 1005 | <td><b><code>T&</code></b></td> |
| 1006 | <td>Passed by reference, with <em>C++ lifetime</em>.</td> |
| 1007 | </tr> |
| 1008 | <tr> |
| 1009 | <td><b><code>T const*</code></b></td> |
| 1010 | <td>Passed by const reference, with <em>C++ lifetime</em>.</td> |
| 1011 | </tr> |
| 1012 | <tr> |
| 1013 | <td><b><code>T const&</code></b></td> |
| 1014 | <td>Passed by const reference, with <em>C++ lifetime</em>.</td> |
| 1015 | </tr> |
| 1016 | </table> |
| 1017 | |
| 1018 | <!--========================================================================--> |
| 1019 | |
| 1020 | <section> |
| 1021 | |
| 1022 | <h2>3.1 - <span id="s3.1">C++ Lifetime</span></h2> |
| 1023 | |
| 1024 | <p> |
| 1025 | The creation and deletion of objects with <em>C++ lifetime</em> is controlled by |
| 1026 | the C++ code. Lua does nothing when it garbage collects a reference to such an |
| 1027 | object. Specifically, the object's destructor is not called (since C++ owns |
| 1028 | it). Care must be taken to ensure that objects with C++ lifetime are not |
| 1029 | deleted while still being referenced by a <code>lua_State*</code>, or else |
| 1030 | undefined behavior results. In the previous examples, an instance of <code>A</code> |
| 1031 | can be passed to Lua with C++ lifetime, like this: |
| 1032 | </p> |
| 1033 | |
| 1034 | <pre> |
| 1035 | A a; |
| 1036 | |
| 1037 | push (L, &a); // pointer to 'a', C++ lifetime |
| 1038 | lua_setglobal (L, "a"); |
| 1039 | |
| 1040 | push (L, (A const*)&a); // pointer to 'a const', C++ lifetime |
| 1041 | lua_setglobal (L, "ac"); |
| 1042 | |
| 1043 | push <A const*> (L, &a); // equivalent to push (L, (A const*)&a) |
| 1044 | lua_setglobal (L, "ac2"); |
| 1045 | |
| 1046 | push (L, new A); // compiles, but will leak memory |
| 1047 | lua_setglobal (L, "ap"); |
| 1048 | </pre> |
| 1049 | |
| 1050 | </section> |
| 1051 | |
| 1052 | <!--========================================================================--> |
| 1053 | |
| 1054 | <section> |
| 1055 | |
| 1056 | <h2>3.2 - <span id="s3.2">Lua Lifetime</span></h2> |
| 1057 | |
| 1058 | <p> |
| 1059 | When an object of a registered class is passed by value to Lua, it will have |
| 1060 | <em>Lua lifetime</em>. A copy of the passed object is constructed inside the |
| 1061 | userdata. When Lua has no more references to the object, it becomes eligible |
| 1062 | for garbage collection. When the userdata is collected, the destructor for |
| 1063 | the class will be called on the object. Care must be taken to ensure that |
| 1064 | objects with Lua lifetime are not accessed by C++ after they are garbage |
| 1065 | collected, or else undefined behavior results. An instance of <code>B</code> |
| 1066 | can be passed to Lua with Lua lifetime this way: |
| 1067 | </p> |
| 1068 | |
| 1069 | <pre> |
| 1070 | B b; |
| 1071 | |
| 1072 | push (L, b); // Copy of b passed, Lua lifetime. |
| 1073 | lua_setglobal (L, "b"); |
| 1074 | </pre> |
| 1075 | |
| 1076 | <p> |
| 1077 | Given the previous code segments, these Lua statements are applicable: |
| 1078 | </p> |
| 1079 | |
| 1080 | <pre> |
| 1081 | print (test.A.staticData) -- Prints the static data member. |
| 1082 | print (test.A.staticProperty) -- Prints the static property member. |
| 1083 | test.A.staticFunc () -- Calls the static method. |
| 1084 | |
| 1085 | print (a.data) -- Prints the data member. |
| 1086 | print (a.prop) -- Prints the property member. |
| 1087 | a:func1 () -- Calls A::func1 (). |
| 1088 | test.A.func1 (a) -- Equivalent to a:func1 (). |
| 1089 | test.A.func1 ("hello") -- Error: "hello" is not a class A. |
| 1090 | a:virtualFunc () -- Calls A::virtualFunc (). |
| 1091 | |
| 1092 | print (b.data) -- Prints B::dataMember. |
| 1093 | print (b.prop) -- Prints inherited property member. |
| 1094 | b:func1 () -- Calls B::func1 (). |
| 1095 | b:func2 () -- Calls B::func2 (). |
| 1096 | test.B.func2 (a) -- Error: a is not a class B. |
| 1097 | test.A.func1 (b) -- Calls A::func1 (). |
| 1098 | b:virtualFunc () -- Calls B::virtualFunc (). |
| 1099 | test.B.virtualFunc (b) -- Calls B::virtualFunc (). |
| 1100 | test.A.virtualFunc (b) -- Calls B::virtualFunc (). |
| 1101 | test.B.virtualFunc (a) -- Error: a is not a class B. |
| 1102 | |
| 1103 | a = nil; collectgarbage () -- 'a' still exists in C++. |
| 1104 | b = nil; collectgarbage () -- Lua calls ~B() on the copy of b. |
| 1105 | </pre> |
| 1106 | |
| 1107 | <p> |
| 1108 | When Lua script creates an object of class type using a registered |
| 1109 | constructor, the resulting value will have Lua lifetime. After Lua no longer |
| 1110 | references the object, it becomes eligible for garbage collection. You can |
| 1111 | still pass these to C++, either by reference or by value. If passed by |
| 1112 | reference, the usual warnings apply about accessing the reference later, |
| 1113 | after it has been garbage collected. |
| 1114 | </p> |
| 1115 | |
| 1116 | </section> |
| 1117 | |
| 1118 | <!--========================================================================--> |
| 1119 | |
| 1120 | <section> |
| 1121 | |
| 1122 | <h2>3.3 - <span id="s3.3">Pointers, References, and Pass by Value</span></h2> |
| 1123 | |
| 1124 | <p> |
| 1125 | When C++ objects are passed from Lua back to C++ as arguments to functions, |
| 1126 | or set as data members, LuaBridge does its best to automate the conversion. |
| 1127 | Using the previous definitions, the following functions may be registered |
| 1128 | to Lua: |
| 1129 | </p> |
| 1130 | |
| 1131 | <pre> |
| 1132 | void func0 (A a); |
| 1133 | void func1 (A* a); |
| 1134 | void func2 (A const* a); |
| 1135 | void func3 (A& a); |
| 1136 | void func4 (A const& a); |
| 1137 | </pre> |
| 1138 | |
| 1139 | <p> |
| 1140 | Executing this Lua code will have the prescribed effect: |
| 1141 | </p> |
| 1142 | |
| 1143 | <pre> |
| 1144 | func0 (a) -- Passes a copy of a, using A's copy constructor. |
| 1145 | func1 (a) -- Passes a pointer to a. |
| 1146 | func2 (a) -- Passes a pointer to a const a. |
| 1147 | func3 (a) -- Passes a reference to a. |
| 1148 | func4 (a) -- Passes a reference to a const a. |
| 1149 | </pre> |
| 1150 | |
| 1151 | <p> |
| 1152 | In the example above, all functions can read the data members and property |
| 1153 | members of <code>a</code>, or call const member functions of <code>a</code>. |
| 1154 | Only <code>func0</code>, <code>func1</code>, and <code>func3</code> can |
| 1155 | modify the data members and data properties, or call non-const member |
| 1156 | functions of <code>a</code>. |
| 1157 | </p> |
| 1158 | |
| 1159 | <p> |
| 1160 | The usual C++ inheritance and pointer assignment rules apply. Given: |
| 1161 | </p> |
| 1162 | |
| 1163 | <pre> |
| 1164 | void func5 (B b); |
| 1165 | void func6 (B* b); |
| 1166 | </pre> |
| 1167 | |
| 1168 | <p> |
| 1169 | These Lua statements hold: |
| 1170 | </p> |
| 1171 | |
| 1172 | <pre> |
| 1173 | func5 (b) - Passes a copy of b, using B's copy constructor. |
| 1174 | func6 (b) - Passes a pointer to b. |
| 1175 | func6 (a) - Error: Pointer to B expected. |
| 1176 | func1 (b) - Okay, b is a subclass of a. |
| 1177 | </pre> |
| 1178 | |
| 1179 | <p> |
| 1180 | When a pointer or pointer to const is passed to Lua and the pointer is null |
| 1181 | (zero), LuaBridge will pass Lua a `nil` instead. When Lua passes a |
| 1182 | <code>nil</code> to C++ where a pointer is expected, a null (zero) is passed |
| 1183 | instead. Attempting to pass a null pointer to a C++ function expecting a |
| 1184 | reference results in <code>lua_error</code> being called. |
| 1185 | </p> |
| 1186 | |
| 1187 | </section> |
| 1188 | |
| 1189 | <!--========================================================================--> |
| 1190 | |
| 1191 | <section> |
| 1192 | |
| 1193 | <h2>3.4 - <span id="s3.4">Shared Lifetime</span></h2> |
| 1194 | |
| 1195 | <p> |
| 1196 | LuaBridge supports a <em>shared lifetime</em> model: dynamically allocated |
| 1197 | and reference counted objects whose ownership is shared by both Lua and C++. |
| 1198 | The object remains in existence until there are no remaining C++ or Lua |
| 1199 | references, and Lua performs its usual garbage collection cycle. A container |
| 1200 | is recognized by a specialization of the <code>ContainerTraits</code> |
| 1201 | template class. LuaBridge will automatically recognize when a data type is |
| 1202 | a container when the correspoding specialization is present. Two styles of |
| 1203 | containers come with LuaBridge, including the necessary specializations. |
| 1204 | </p> |
| 1205 | |
| 1206 | <!--========================================================================--> |
| 1207 | |
| 1208 | <section> |
| 1209 | |
| 1210 | <h3>3.4.1 - <span id="s3.4.1">Class RefCountedObjectPtr</span></h3> |
| 1211 | |
| 1212 | <p> |
| 1213 | This is an intrusive style container. Your existing class declaration must be |
| 1214 | changed to be also derived from <code>RefCountedObject</code>. Given |
| 1215 | <code>class T</code>, derived from <code>RefCountedObject</code>, the container |
| 1216 | <code>RefCountedObjectPtr <T></code>` may be used. In order for |
| 1217 | reference counts to be maintained properly, all C++ code must store a |
| 1218 | container instead of the pointer. This is similar in style to |
| 1219 | <code>std::shared_ptr</code> although there are slight differences. For |
| 1220 | example: |
| 1221 | </p> |
| 1222 | |
| 1223 | <pre> |
| 1224 | // A is reference counted. |
| 1225 | struct A : public RefCountedObject |
| 1226 | { |
| 1227 | void foo () { } |
| 1228 | }; |
| 1229 | |
| 1230 | struct B |
| 1231 | { |
| 1232 | RefCountedObjectPtr <A> a; // holds a reference to A |
| 1233 | }; |
| 1234 | |
| 1235 | void bar (RefCountedObjectPtr <A> a) |
| 1236 | { |
| 1237 | a->foo (); |
| 1238 | } |
| 1239 | </pre> |
| 1240 | |
| 1241 | </section> |
| 1242 | |
| 1243 | <!--========================================================================--> |
| 1244 | |
| 1245 | <section> |
| 1246 | |
| 1247 | <h3>3.4.2 - <span id="s3.4.2">Class RefCountedPtr</span></h3> |
| 1248 | |
| 1249 | <p> |
| 1250 | This is a non intrusive reference counted pointer. The reference counts are |
| 1251 | kept in a global hash table, which does incur a small performance penalty. |
| 1252 | However, it does not require changing any already existing class declarations. |
| 1253 | This is especially useful when the classes to be registered come from a third |
| 1254 | party library and cannot be modified. To use it, simply wrap all pointers |
| 1255 | to class objects with the container instead: |
| 1256 | </p> |
| 1257 | |
| 1258 | <pre> |
| 1259 | struct A |
| 1260 | { |
| 1261 | void foo () { } |
| 1262 | }; |
| 1263 | |
| 1264 | struct B |
| 1265 | { |
| 1266 | RefCountedPtr <A> a; |
| 1267 | }; |
| 1268 | |
| 1269 | RefCountedPtr <A> createA () |
| 1270 | { |
| 1271 | return new A; |
| 1272 | } |
| 1273 | |
| 1274 | void bar (RefCountedPtr <A> a) |
| 1275 | { |
| 1276 | a->foo (); |
| 1277 | } |
| 1278 | |
| 1279 | void callFoo () |
| 1280 | { |
| 1281 | bar (createA ()); |
| 1282 | |
| 1283 | // The created A will be destroyed |
| 1284 | // when we leave this scope |
| 1285 | } |
| 1286 | </pre> |
| 1287 | |
| 1288 | </section> |
| 1289 | |
| 1290 | <!--========================================================================--> |
| 1291 | |
| 1292 | <section> |
| 1293 | |
| 1294 | <h3>3.4.3 - <span id="s3.4.3">User-defined Containers</span></h3> |
| 1295 | |
| 1296 | <p> |
| 1297 | If you have your own container, you must provide a specialization of |
| 1298 | <code>ContainerTraits</code> in the <code>luabridge</code> namespace for your |
| 1299 | type before it will be recognized by LuaBridge (or else the code will not |
| 1300 | compile): |
| 1301 | </p> |
| 1302 | |
| 1303 | <pre> |
| 1304 | template <class T> |
| 1305 | struct ContainerTraits <CustomContainer <T> > |
| 1306 | { |
| 1307 | typedef typename T Type; |
| 1308 | |
| 1309 | static T* get (CustomContainer <T> const& c) |
| 1310 | { |
| 1311 | return c.getPointerToObject (); |
| 1312 | } |
| 1313 | }; |
| 1314 | </pre> |
| 1315 | |
| 1316 | <p> |
| 1317 | Standard containers like <code>std::shared_ptr</code> or |
| 1318 | <code>boost::shared_ptr</code> <b>will not work</b>. This is because of type |
| 1319 | erasure; when the object goes from C++ to Lua and back to C++, there is no |
| 1320 | way to associate the object with the original container. The new container is |
| 1321 | constructed from a pointer to the object instead of an existing container. |
| 1322 | The result is undefined behavior since there are now two sets of reference |
| 1323 | counts. |
| 1324 | </p> |
| 1325 | |
| 1326 | </section> |
| 1327 | |
| 1328 | <!--========================================================================--> |
| 1329 | |
| 1330 | <section> |
| 1331 | |
| 1332 | <h3>3.4.4 - <span id="s3.4.4">Container Constructors</span></h3> |
| 1333 | |
| 1334 | <p> |
| 1335 | When a constructor is registered for a class, there is an additional |
| 1336 | optional second template parameter describing the type of container to use. |
| 1337 | If this parameter is specified, calls to the constructor will create the |
| 1338 | object dynamically, via operator new, and place it a container of that |
| 1339 | type. The container must have been previously specialized in |
| 1340 | <code>ContainerTraits</code>, or else a compile error will result. This code |
| 1341 | will register two objects, each using a constructor that creates an object |
| 1342 | with Lua lifetime using the specified container: |
| 1343 | </p> |
| 1344 | |
| 1345 | <pre> |
| 1346 | class C : public RefCountedObject |
| 1347 | { |
| 1348 | C () { } |
| 1349 | }; |
| 1350 | |
| 1351 | class D |
| 1352 | { |
| 1353 | D () { } |
| 1354 | }; |
| 1355 | |
| 1356 | getGlobalNamespace (L) |
| 1357 | .beginNamespace ("test") |
| 1358 | .beginClass <C> ("C") |
| 1359 | .addConstructor <void (*) (void), RefCountedObjectPtr <C> > () |
| 1360 | .endClass () |
| 1361 | .beginClass <D> ("D") |
| 1362 | .addConstructor <void (*) (void), RefCountedPtr <D> > () |
| 1363 | .endClass (); |
| 1364 | .endNamespace () |
| 1365 | </pre> |
| 1366 | |
| 1367 | </section> |
| 1368 | |
| 1369 | <!--========================================================================--> |
| 1370 | |
| 1371 | </section> |
| 1372 | |
| 1373 | <section> |
| 1374 | |
| 1375 | <h2>3.5 - <span id="s3.5">Mixing Lifetimes</span></h2> |
| 1376 | |
| 1377 | <p> |
| 1378 | Mixing object lifetime models is entirely possible, subject to the usual |
| 1379 | caveats of holding references to objects which could get deleted. For |
| 1380 | example, C++ can be called from Lua with a pointer to an object of class |
| 1381 | type; the function can modify the object or call non-const data members. |
| 1382 | These modifications are visible to Lua (since they both refer to the same |
| 1383 | object). An object store in a container can be passed to a function expecting |
| 1384 | a pointer. These conversion work seamlessly. |
| 1385 | <p> |
| 1386 | |
| 1387 | </section> |
| 1388 | |
| 1389 | <!--========================================================================--> |
| 1390 | |
| 1391 | <section> |
| 1392 | |
| 1393 | <h2>3.6 - <span id="s3.6">Convenience Functions</span></h2> |
| 1394 | |
| 1395 | <p> |
| 1396 | The <code>setGlobal</code> function can be used to assign any convertible |
| 1397 | value into a global variable. |
| 1398 | </p> |
| 1399 | |
| 1400 | </section> |
| 1401 | |
| 1402 | <!--========================================================================--> |
| 1403 | |
| 1404 | </section> |
| 1405 | |
| 1406 | <section> |
| 1407 | |
| 1408 | <h1>4 - <span id="s4">Accessing Lua from C++</span></h1> |
| 1409 | |
| 1410 | <p> |
| 1411 | Because Lua is a <em>dynamically typed language</em>, special consideration |
| 1412 | is required to map values in Lua to C++. The following sections describe the |
| 1413 | classes and functions used for representing Lua types. Only the essential |
| 1414 | operations are explained; To gain understanding of all available functions, |
| 1415 | please refer to the documentation comments in the corresponding source files. |
| 1416 | </p> |
| 1417 | |
| 1418 | <!--========================================================================--> |
| 1419 | |
| 1420 | <section> |
| 1421 | |
| 1422 | <h2>4.1 - <span id="s4.1">Class LuaRef</span></h2> |
| 1423 | |
| 1424 | <p> |
| 1425 | The <code>LuaRef</code> class is a container which references any Lua type. |
| 1426 | It can hold anything which a Lua variable can hold: <strong>nil</strong>, |
| 1427 | number, boolean, string, table, function, thread, userdata, and |
| 1428 | lightuserdata. Because <code>LuaRef</code> uses the <code>Stack</code> |
| 1429 | template specializations to do its work, classes, functions, and data |
| 1430 | exported to Lua through namespace registrations can also be stored (these |
| 1431 | are instances of userdata). In general, a <code>LuaRef</code> can represent |
| 1432 | any <em>convertible</em> C++ type as well as all Lua types. |
| 1433 | </p> |
| 1434 | |
| 1435 | <p> |
| 1436 | A <code>LuaRef</code> variable constructed with no parameters produces a |
| 1437 | reference to <strong>nil</strong>: |
| 1438 | </p> |
| 1439 | |
| 1440 | <pre> |
| 1441 | LuaRef v (L); // References nil |
| 1442 | </pre> |
| 1443 | |
| 1444 | <p> |
| 1445 | To construct a <code>LuaRef</code> to a specific value, the two parameter |
| 1446 | constructor is used: |
| 1447 | </p> |
| 1448 | |
| 1449 | <pre> |
| 1450 | LuaRef v1 (L, 1); // A LUA_TNUMBER |
| 1451 | LuaRef v2 (L, 1.1); // Also a LUA_TNUMBER |
| 1452 | LuaRef v3 (L, true); // A LUA_TBOOLEAN |
| 1453 | LuaRef v4 (L, "string"); // A LUA_TSTRING |
| 1454 | </pre> |
| 1455 | |
| 1456 | <p> |
| 1457 | The functions <code>newTable</code> and <code>getGlobal</code> create |
| 1458 | references to new empty table and an existing value in the global table |
| 1459 | respectively: |
| 1460 | </p> |
| 1461 | |
| 1462 | <pre> |
| 1463 | LuaRef v1 = newTable (L); // Create a new table |
| 1464 | LuaRef v2 = getGlobal (L, "print") // Reference to _G ["print"] |
| 1465 | </pre> |
| 1466 | |
| 1467 | <p> |
| 1468 | A <code>LuaRef</code> can hold classes <em>registered</em> using LuaBridge: |
| 1469 | </p> |
| 1470 | |
| 1471 | <pre> |
| 1472 | class A; |
| 1473 | //... |
| 1474 | LuaRef v (L, new A); // A LuaBridge userdata holding a pointer to A |
| 1475 | </pre> |
| 1476 | |
| 1477 | <p> |
| 1478 | Any convertible type may be assigned to an already-existing <code>LuaRef</code>: |
| 1479 | </p> |
| 1480 | |
| 1481 | <pre> |
| 1482 | LuaRef v (L); // Nil |
| 1483 | v = newTable (L); // An empty table |
| 1484 | v = "string" // A string. The prevous value becomes |
| 1485 | // eligible for garbage collection. |
| 1486 | </pre> |
| 1487 | |
| 1488 | <p> |
| 1489 | A <code>LuaRef</code> is itself a convertible type, and the convertible |
| 1490 | type <code>Nil</code> can be used to represent a Lua <strong>nil</strong>. |
| 1491 | </p> |
| 1492 | |
| 1493 | <pre> |
| 1494 | LuaRef v1 (L, "x"); // assign "x" |
| 1495 | LuaRef v2 (L, "y"); // assign "y" |
| 1496 | v2 = v1; // v2 becomes "x" |
| 1497 | v1 = "z"; // v1 becomes "z", v2 is unchanged |
| 1498 | v1 = newTable (L); // An empty table |
| 1499 | v2 = v1; // v2 references the same table as v1 |
| 1500 | v1 = Nil (); // v1 becomes nil, table is still |
| 1501 | // referenced by v2. |
| 1502 | </pre> |
| 1503 | |
| 1504 | <p> |
| 1505 | Values stored in a <code>LuaRef</code> object obey the same rules as |
| 1506 | variables in Lua: tables, functions, threads, and full userdata values are |
| 1507 | <em>objects</em>. The <code>LuaRef</code> does not actually <em>contain</em> |
| 1508 | these values, only <em>references</em> to them. Assignment, parameter |
| 1509 | passing, and function returns always manipulate references to such values; |
| 1510 | these operations do not imply any kind of copy. |
| 1511 | </p> |
| 1512 | |
| 1513 | <!--========================================================================--> |
| 1514 | |
| 1515 | <section> |
| 1516 | |
| 1517 | <h3>4.1.1 - <span id="s4.1.1">Type Conversions</span></h3> |
| 1518 | |
| 1519 | <p> |
| 1520 | A universal C++ conversion operator is provided for implicit conversions |
| 1521 | which allow a <code>LuaRef</code> to be used where any convertible type is |
| 1522 | expected. These operations will all compile: |
| 1523 | </p> |
| 1524 | |
| 1525 | <pre> |
| 1526 | void passInt (int); |
| 1527 | void passBool (bool); |
| 1528 | void passString (std::string); |
| 1529 | void passObject (A*); |
| 1530 | |
| 1531 | LuaRef v (L); |
| 1532 | //... |
| 1533 | passInt (v); // implicit conversion to int |
| 1534 | passBool (v); // implicit conversion to bool |
| 1535 | passString (v); // implicit conversion to string |
| 1536 | passObject (v); // must hold a registered LuaBridge class or a |
| 1537 | // lua_error() will be called. |
| 1538 | </pre> |
| 1539 | |
| 1540 | <p> |
| 1541 | Since Lua types are dynamic, the conversion is performed at run time using |
| 1542 | traditional functions like <code>lua_toboolean</code> or |
| 1543 | <code>lua_tostring</code>. In some cases, the type information may be |
| 1544 | incorrect especially when passing objects of registered class types. |
| 1545 | When performing these conversions, LuaBridge may raise a Lua error by |
| 1546 | directly or indirectly calling <code>lua_error</code> To be bullet-proof, |
| 1547 | such code must either be wrapped in a <code>lua_pcall</code>, or you must |
| 1548 | install a Lua <em>panic function</em> that throws an exception which you |
| 1549 | can catch. |
| 1550 | </p> |
| 1551 | |
| 1552 | <p> |
| 1553 | When an explicit conversion is required (such as when writing templates), |
| 1554 | use the <code>cast</code> template function or an explicit C++ style cast. |
| 1555 | </p> |
| 1556 | |
| 1557 | <pre> |
| 1558 | void passString (std::string); |
| 1559 | |
| 1560 | LuaRef v (L); |
| 1561 | |
| 1562 | // The following are all equivalent: |
| 1563 | |
| 1564 | passString (std::string (v)); |
| 1565 | passString ((std::string)v); |
| 1566 | passString (static_cast <std::string> (v)); |
| 1567 | passString (v.cast <std::string> ()); |
| 1568 | </pre> |
| 1569 | |
| 1570 | </section> |
| 1571 | |
| 1572 | <!--========================================================================--> |
| 1573 | |
| 1574 | <section> |
| 1575 | |
| 1576 | <h3>4.1.2 - <span id="s4.1.2">Visual Studio 2010, 2012</span></h3> |
| 1577 | |
| 1578 | <p> |
| 1579 | There is a defect with all versions of Visual Studio up to and including |
| 1580 | Visual Studio 2012 which prevents the implicit conversion operator from |
| 1581 | being applied when it is used as an operand in a boolean operator: |
| 1582 | </p> |
| 1583 | |
| 1584 | <pre> |
| 1585 | LuaRef v1 (L); |
| 1586 | LuaRef v2 (L); |
| 1587 | |
| 1588 | if (v1 || v2) { } // Compile error in Visual Studio |
| 1589 | |
| 1590 | // Work-arounds: |
| 1591 | if (v1.cast <bool> () || v2.cast <bool> ()) { } |
| 1592 | if (bool (v1) || bool (v2)) { } |
| 1593 | </pre> |
| 1594 | |
| 1595 | </section> |
| 1596 | |
| 1597 | <!--========================================================================--> |
| 1598 | |
| 1599 | </section> |
| 1600 | |
| 1601 | <section> |
| 1602 | |
| 1603 | <h2>4.2 - <span id="s4.2">Table Proxies</span></h2> |
| 1604 | |
| 1605 | <p> |
| 1606 | As tables are the sole data structuring mechanism in Lua, the |
| 1607 | <code>LuaRef</code> class provides robust facilities for accessing and |
| 1608 | manipulating table elements using a simple, precise syntax. Any convertible |
| 1609 | type may be used as a key or value. Applying the array indexing operator |
| 1610 | <code>[]</code> to a <code>LuaRef</code> returns a special temporary object |
| 1611 | called a <em>table proxy</em> which supports all the operations which can |
| 1612 | be performed on a <code>LuaRef</code>. In addition, assignments made to |
| 1613 | table proxies change the underlying table. Because table proxies are |
| 1614 | compiler-created temporary objects, you don't work with them directly. A |
| 1615 | LuaBridge table proxy should not be confused with the Lua proxy table |
| 1616 | technique described in the book "Programming in Lua"; the LuaBridge table |
| 1617 | proxy is simply an intermediate C++ class object that works behind the |
| 1618 | scenes to make table manipulation syntax conform to C++ idioms. These |
| 1619 | operations all invoke table proxies: |
| 1620 | </p> |
| 1621 | |
| 1622 | <pre> |
| 1623 | LuaRef v (L); |
| 1624 | v = newTable (L); |
| 1625 | |
| 1626 | v ["name"] = "John Doe"; // string key, string value |
| 1627 | v [1] = 200; // integer key, integer value |
| 1628 | v [2] = newTable (L); // integer key, LuaRef value |
| 1629 | v [3] = v [1]; // assign 200 to integer index 3 |
| 1630 | v [1] = 100; // v[1] is 100, v[3] is still 200 |
| 1631 | v [3] = v [2]; // v[2] and v[3] reference the same table |
| 1632 | v [2] = Nil (); // Removes the value with key = 2. The table |
| 1633 | // is still referenced by v[3]. |
| 1634 | </pre> |
| 1635 | |
| 1636 | </section> |
| 1637 | |
| 1638 | <!--========================================================================--> |
| 1639 | |
| 1640 | <section> |
| 1641 | |
| 1642 | <h2>4.3 - <span id="s4.3">Calling Lua</span></h2> |
| 1643 | |
| 1644 | <p> |
| 1645 | Table proxies and <code>LuaRef</code> objects provide a convenient syntax |
| 1646 | for invoking <code>lua_pcall</code> on suitable referenced object. This |
| 1647 | includes C functions, Lua functions, or Lua objects with an appropriate |
| 1648 | <code>__call</code> metamethod set. The provided implementation supports |
| 1649 | up to eight parameters (although more can be supported by adding new |
| 1650 | functions). Any convertible C++ type can be passed as a parameter in its |
| 1651 | native format. The return value of the function call is provided as a |
| 1652 | <code>LuaRef</code>, which may be <strong>nil</strong>. |
| 1653 | </p> |
| 1654 | |
| 1655 | <pre class="split"> |
| 1656 | LuaRef same = getGlobal (L, "same"); |
| 1657 | |
| 1658 | // These all evaluate to true |
| 1659 | same (1,1); |
| 1660 | !same (1,2); |
| 1661 | same ("text", "text"); |
| 1662 | !same (1, "text"); |
| 1663 | same (1, 1, 2); // third param ignored |
| 1664 | </pre> |
| 1665 | |
| 1666 | <pre class="split"> |
| 1667 | function same (arg1, arg) |
| 1668 | return arg1 == arg2 |
| 1669 | end |
| 1670 | </pre> |
| 1671 | |
| 1672 | <p> |
| 1673 | Table proxies support all of the Lua call notation that <code>LuaRef</code> |
| 1674 | supports, making these statements possible: |
| 1675 | </p> |
| 1676 | |
| 1677 | <pre class="split"> |
| 1678 | LuaRef v = getGlobal (L, "t"); |
| 1679 | |
| 1680 | t[1](); |
| 1681 | t[2]("a", "b"); |
| 1682 | t[2](t[1]); // Call t[3] with the value in t[2] |
| 1683 | t[4]=t[3](); // Call t[3] and store the result in t[4]. |
| 1684 | |
| 1685 | t [t[5]()] = "wow"; // Store "wow" at the key returned by |
| 1686 | // the call to t[5] |
| 1687 | </pre> |
| 1688 | |
| 1689 | <pre class="split"> |
| 1690 | t = {} |
| 1691 | t[1] = function () print ("hello") end |
| 1692 | t[2] = function (u, v) print (u, v) end |
| 1693 | t[3] = "foo" |
| 1694 | </pre> |
| 1695 | |
| 1696 | <!--========================================================================--> |
| 1697 | |
| 1698 | <h3>4.3.1 - <span id="s4.3.1">Class LuaException</span></h3> |
| 1699 | |
| 1700 | <section > |
| 1701 | |
| 1702 | <p> |
| 1703 | When <code>LuaRef</code> is used to call into Lua using the <code>()</code> |
| 1704 | operator it issues a protected call using <code>lua_pcall</code>. LuaBridge |
| 1705 | uses the C++ exception handling mechanism, throwing a <code>LuaException</code> |
| 1706 | object: |
| 1707 | </p> |
| 1708 | |
| 1709 | <pre class="split"> |
| 1710 | LuaRef f (L) = getGlobal (L, "fail"); |
| 1711 | |
| 1712 | try { |
| 1713 | f (); |
| 1714 | } |
| 1715 | catch (LuaException const& e) { |
| 1716 | std::cerr && e.what (); |
| 1717 | } |
| 1718 | </pre> |
| 1719 | |
| 1720 | <pre class="split"> |
| 1721 | function fail () |
| 1722 | error ("A problem occurred") |
| 1723 | end |
| 1724 | </pre> |
| 1725 | |
| 1726 | </section> |
| 1727 | |
| 1728 | <!--========================================================================--> |
| 1729 | |
| 1730 | </section> |
| 1731 | |
| 1732 | <!--========================================================================--> |
| 1733 | |
| 1734 | </section> |
| 1735 | |
| 1736 | <section> |
| 1737 | |
| 1738 | <h1>5 - <span id="s5">Security</span></h1> |
| 1739 | |
| 1740 | <p> |
| 1741 | The metatables and userdata that LuaBridge creates in the `lua_State*` are |
| 1742 | protected using a security system, to eliminate the possibility of undefined |
| 1743 | behavior resulting from scripted manipulation of the environment. The |
| 1744 | security system has these components: |
| 1745 | </p> |
| 1746 | |
| 1747 | <ul class="bullets"> |
| 1748 | <li> |
| 1749 | Class and const class tables use the <em>table proxy</em> technique. The |
| 1750 | corresponding metatables have <code>__index</code> and <code>__newindex</code> |
| 1751 | metamethods, so these class tables are immutable from Lua. |
| 1752 | <li> |
| 1753 | Metatables have <code>__metatable</code> set to a boolean value. Scripts |
| 1754 | cannot obtain the metatable from a LuaBridge object. |
| 1755 | <li> |
| 1756 | Classes are mapped to metatables through the registry, which Lua scripts |
| 1757 | cannot access. The global environment does not expose metatables |
| 1758 | <li> |
| 1759 | Metatables created by LuaBridge are tagged with a lightuserdata key which |
| 1760 | is unique in the process. Other libraries cannot forge a LuaBridge |
| 1761 | metatable. |
| 1762 | </ul> |
| 1763 | |
| 1764 | <p> |
| 1765 | This security system can be easily bypassed if scripts are given access to |
| 1766 | the debug library (or functionality similar to it, i.e. a raw `getmetatable`). |
| 1767 | The security system can also be defeated by C code in the host, either by |
| 1768 | revealing the unique lightuserdata key to another module or by putting a |
| 1769 | LuaBridge metatable in a place that can be accessed by scripts. |
| 1770 | </p> |
| 1771 | |
| 1772 | <p> |
| 1773 | When a class member function is called, or class property member accessed, |
| 1774 | the `this` pointer is type-checked. This is because member functions exposed |
| 1775 | to Lua are just plain functions that usually get called with the Lua colon |
| 1776 | notation, which passes the object in question as the first parameter. Lua's |
| 1777 | dynamic typing makes this type-checking mandatory to prevent undefined |
| 1778 | behavior resulting from improper use. |
| 1779 | </p> |
| 1780 | |
| 1781 | <p> |
| 1782 | If a type check error occurs, LuaBridge uses the <code>lua_error</code> |
| 1783 | mechanism to trigger a failure. A host program can always recover from |
| 1784 | an error through the use of <code>lua_pcall</code>; proper usage of |
| 1785 | LuaBridge will never result in undefined behavior. |
| 1786 | </p> |
| 1787 | |
| 1788 | </section> |
| 1789 | |
| 1790 | <!--========================================================================--> |
| 1791 | |
| 1792 | </body> |
| 1793 | </html> |
| 1794 | |
trunk/3rdparty/luabridge/Source/LuaBridge/detail/CFunctions.h
| r0 | r242832 | |
| 1 | //------------------------------------------------------------------------------ |
| 2 | /* |
| 3 | https://github.com/vinniefalco/LuaBridge |
| 4 | |
| 5 | Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com> |
| 6 | |
| 7 | License: The MIT License (http://www.opensource.org/licenses/mit-license.php) |
| 8 | |
| 9 | Permission is hereby granted, free of charge, to any person obtaining a copy |
| 10 | of this software and associated documentation files (the "Software"), to deal |
| 11 | in the Software without restriction, including without limitation the rights |
| 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| 13 | copies of the Software, and to permit persons to whom the Software is |
| 14 | furnished to do so, subject to the following conditions: |
| 15 | |
| 16 | The above copyright notice and this permission notice shall be included in all |
| 17 | copies or substantial portions of the Software. |
| 18 | |
| 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| 25 | SOFTWARE. |
| 26 | */ |
| 27 | //============================================================================== |
| 28 | |
| 29 | // We use a structure so we can define everything in the header. |
| 30 | // |
| 31 | struct CFunc |
| 32 | { |
| 33 | //---------------------------------------------------------------------------- |
| 34 | /** |
| 35 | __index metamethod for a namespace or class static members. |
| 36 | |
| 37 | This handles: |
| 38 | Retrieving functions and class static methods, stored in the metatable. |
| 39 | Reading global and class static data, stored in the __propget table. |
| 40 | Reading global and class properties, stored in the __propget table. |
| 41 | */ |
| 42 | static int indexMetaMethod (lua_State* L) |
| 43 | { |
| 44 | int result = 0; |
| 45 | lua_getmetatable (L, 1); // push metatable of arg1 |
| 46 | for (;;) |
| 47 | { |
| 48 | lua_pushvalue (L, 2); // push key arg2 |
| 49 | lua_rawget (L, -2); // lookup key in metatable |
| 50 | if (lua_isnil (L, -1)) // not found |
| 51 | { |
| 52 | lua_pop (L, 1); // discard nil |
| 53 | rawgetfield (L, -1, "__propget"); // lookup __propget in metatable |
| 54 | lua_pushvalue (L, 2); // push key arg2 |
| 55 | lua_rawget (L, -2); // lookup key in __propget |
| 56 | lua_remove (L, -2); // discard __propget |
| 57 | if (lua_iscfunction (L, -1)) |
| 58 | { |
| 59 | lua_remove (L, -2); // discard metatable |
| 60 | lua_pushvalue (L, 1); // push arg1 |
| 61 | lua_call (L, 1, 1); // call cfunction |
| 62 | result = 1; |
| 63 | break; |
| 64 | } |
| 65 | else |
| 66 | { |
| 67 | assert (lua_isnil (L, -1)); |
| 68 | lua_pop (L, 1); // discard nil and fall through |
| 69 | } |
| 70 | } |
| 71 | else |
| 72 | { |
| 73 | assert (lua_istable (L, -1) || lua_iscfunction (L, -1)); |
| 74 | lua_remove (L, -2); |
| 75 | result = 1; |
| 76 | break; |
| 77 | } |
| 78 | |
| 79 | rawgetfield (L, -1, "__parent"); |
| 80 | if (lua_istable (L, -1)) |
| 81 | { |
| 82 | // Remove metatable and repeat the search in __parent. |
| 83 | lua_remove (L, -2); |
| 84 | } |
| 85 | else |
| 86 | { |
| 87 | // Discard metatable and return nil. |
| 88 | assert (lua_isnil (L, -1)); |
| 89 | lua_remove (L, -2); |
| 90 | result = 1; |
| 91 | break; |
| 92 | } |
| 93 | } |
| 94 | |
| 95 | return result; |
| 96 | } |
| 97 | |
| 98 | //---------------------------------------------------------------------------- |
| 99 | /** |
| 100 | __newindex metamethod for a namespace or class static members. |
| 101 | |
| 102 | The __propset table stores proxy functions for assignment to: |
| 103 | Global and class static data. |
| 104 | Global and class properties. |
| 105 | */ |
| 106 | static int newindexMetaMethod (lua_State* L) |
| 107 | { |
| 108 | int result = 0; |
| 109 | lua_getmetatable (L, 1); // push metatable of arg1 |
| 110 | for (;;) |
| 111 | { |
| 112 | rawgetfield (L, -1, "__propset"); // lookup __propset in metatable |
| 113 | assert (lua_istable (L, -1)); |
| 114 | lua_pushvalue (L, 2); // push key arg2 |
| 115 | lua_rawget (L, -2); // lookup key in __propset |
| 116 | lua_remove (L, -2); // discard __propset |
| 117 | if (lua_iscfunction (L, -1)) // ensure value is a cfunction |
| 118 | { |
| 119 | lua_remove (L, -2); // discard metatable |
| 120 | lua_pushvalue (L, 3); // push new value arg3 |
| 121 | lua_call (L, 1, 0); // call cfunction |
| 122 | result = 0; |
| 123 | break; |
| 124 | } |
| 125 | else |
| 126 | { |
| 127 | assert (lua_isnil (L, -1)); |
| 128 | lua_pop (L, 1); |
| 129 | } |
| 130 | |
| 131 | rawgetfield (L, -1, "__parent"); |
| 132 | if (lua_istable (L, -1)) |
| 133 | { |
| 134 | // Remove metatable and repeat the search in __parent. |
| 135 | lua_remove (L, -2); |
| 136 | } |
| 137 | else |
| 138 | { |
| 139 | assert (lua_isnil (L, -1)); |
| 140 | lua_pop (L, 2); |
| 141 | result = luaL_error (L,"no writable variable '%s'", lua_tostring (L, 2)); |
| 142 | } |
| 143 | } |
| 144 | |
| 145 | return result; |
| 146 | } |
| 147 | |
| 148 | //---------------------------------------------------------------------------- |
| 149 | /** |
| 150 | lua_CFunction to report an error writing to a read-only value. |
| 151 | |
| 152 | The name of the variable is in the first upvalue. |
| 153 | */ |
| 154 | static int readOnlyError (lua_State* L) |
| 155 | { |
| 156 | std::string s; |
| 157 | |
| 158 | s = s + "'" + lua_tostring (L, lua_upvalueindex (1)) + "' is read-only"; |
| 159 | |
| 160 | return luaL_error (L, s.c_str ()); |
| 161 | } |
| 162 | |
| 163 | //---------------------------------------------------------------------------- |
| 164 | /** |
| 165 | lua_CFunction to get a variable. |
| 166 | |
| 167 | This is used for global variables or class static data members. |
| 168 | |
| 169 | The pointer to the data is in the first upvalue. |
| 170 | */ |
| 171 | template <class T> |
| 172 | static int getVariable (lua_State* L) |
| 173 | { |
| 174 | assert (lua_islightuserdata (L, lua_upvalueindex (1))); |
| 175 | T const* ptr = static_cast <T const*> (lua_touserdata (L, lua_upvalueindex (1))); |
| 176 | assert (ptr != 0); |
| 177 | Stack <T>::push (L, *ptr); |
| 178 | return 1; |
| 179 | } |
| 180 | |
| 181 | //---------------------------------------------------------------------------- |
| 182 | /** |
| 183 | lua_CFunction to set a variable. |
| 184 | |
| 185 | This is used for global variables or class static data members. |
| 186 | |
| 187 | The pointer to the data is in the first upvalue. |
| 188 | */ |
| 189 | template <class T> |
| 190 | static int setVariable (lua_State* L) |
| 191 | { |
| 192 | assert (lua_islightuserdata (L, lua_upvalueindex (1))); |
| 193 | T* ptr = static_cast <T*> (lua_touserdata (L, lua_upvalueindex (1))); |
| 194 | assert (ptr != 0); |
| 195 | *ptr = Stack <T>::get (L, 1); |
| 196 | return 0; |
| 197 | } |
| 198 | |
| 199 | //---------------------------------------------------------------------------- |
| 200 | /** |
| 201 | lua_CFunction to call a function with a return value. |
| 202 | |
| 203 | This is used for global functions, global properties, class static methods, |
| 204 | and class static properties. |
| 205 | |
| 206 | The function pointer is in the first upvalue. |
| 207 | */ |
| 208 | template <class FnPtr, |
| 209 | class ReturnType = typename FuncTraits <FnPtr>::ReturnType> |
| 210 | struct Call |
| 211 | { |
| 212 | typedef typename FuncTraits <FnPtr>::Params Params; |
| 213 | static int f (lua_State* L) |
| 214 | { |
| 215 | assert (isfulluserdata (L, lua_upvalueindex (1))); |
| 216 | FnPtr const& fnptr = *static_cast <FnPtr const*> (lua_touserdata (L, lua_upvalueindex (1))); |
| 217 | assert (fnptr != 0); |
| 218 | ArgList <Params> args (L); |
| 219 | Stack <typename FuncTraits <FnPtr>::ReturnType>::push (L, FuncTraits <FnPtr>::call (fnptr, args)); |
| 220 | return 1; |
| 221 | } |
| 222 | }; |
| 223 | |
| 224 | //---------------------------------------------------------------------------- |
| 225 | /** |
| 226 | lua_CFunction to call a function with no return value. |
| 227 | |
| 228 | This is used for global functions, global properties, class static methods, |
| 229 | and class static properties. |
| 230 | |
| 231 | The function pointer is in the first upvalue. |
| 232 | */ |
| 233 | template <class FnPtr> |
| 234 | struct Call <FnPtr, void> |
| 235 | { |
| 236 | typedef typename FuncTraits <FnPtr>::Params Params; |
| 237 | static int f (lua_State* L) |
| 238 | { |
| 239 | assert (isfulluserdata (L, lua_upvalueindex (1))); |
| 240 | FnPtr const& fnptr = *static_cast <FnPtr const*> (lua_touserdata (L, lua_upvalueindex (1))); |
| 241 | assert (fnptr != 0); |
| 242 | ArgList <Params> args (L); |
| 243 | FuncTraits <FnPtr>::call (fnptr, args); |
| 244 | return 0; |
| 245 | } |
| 246 | }; |
| 247 | |
| 248 | //---------------------------------------------------------------------------- |
| 249 | /** |
| 250 | lua_CFunction to call a class member function with a return value. |
| 251 | |
| 252 | The member function pointer is in the first upvalue. |
| 253 | The class userdata object is at the top of the Lua stack. |
| 254 | */ |
| 255 | template <class MemFnPtr, |
| 256 | class ReturnType = typename FuncTraits <MemFnPtr>::ReturnType> |
| 257 | struct CallMember |
| 258 | { |
| 259 | typedef typename FuncTraits <MemFnPtr>::ClassType T; |
| 260 | typedef typename FuncTraits <MemFnPtr>::Params Params; |
| 261 | |
| 262 | static int f (lua_State* L) |
| 263 | { |
| 264 | assert (isfulluserdata (L, lua_upvalueindex (1))); |
| 265 | T* const t = Userdata::get <T> (L, 1, false); |
| 266 | MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1))); |
| 267 | assert (fnptr != 0); |
| 268 | ArgList <Params, 2> args (L); |
| 269 | Stack <ReturnType>::push (L, FuncTraits <MemFnPtr>::call (t, fnptr, args)); |
| 270 | return 1; |
| 271 | } |
| 272 | }; |
| 273 | |
| 274 | template <class MemFnPtr, |
| 275 | class ReturnType = typename FuncTraits <MemFnPtr>::ReturnType> |
| 276 | struct CallConstMember |
| 277 | { |
| 278 | typedef typename FuncTraits <MemFnPtr>::ClassType T; |
| 279 | typedef typename FuncTraits <MemFnPtr>::Params Params; |
| 280 | |
| 281 | static int f (lua_State* L) |
| 282 | { |
| 283 | assert (isfulluserdata (L, lua_upvalueindex (1))); |
| 284 | T const* const t = Userdata::get <T> (L, 1, true); |
| 285 | MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1))); |
| 286 | assert (fnptr != 0); |
| 287 | ArgList <Params, 2> args(L); |
| 288 | Stack <ReturnType>::push (L, FuncTraits <MemFnPtr>::call (t, fnptr, args)); |
| 289 | return 1; |
| 290 | } |
| 291 | }; |
| 292 | |
| 293 | //---------------------------------------------------------------------------- |
| 294 | /** |
| 295 | lua_CFunction to call a class member function with no return value. |
| 296 | |
| 297 | The member function pointer is in the first upvalue. |
| 298 | The class userdata object is at the top of the Lua stack. |
| 299 | */ |
| 300 | template <class MemFnPtr> |
| 301 | struct CallMember <MemFnPtr, void> |
| 302 | { |
| 303 | typedef typename FuncTraits <MemFnPtr>::ClassType T; |
| 304 | typedef typename FuncTraits <MemFnPtr>::Params Params; |
| 305 | |
| 306 | static int f (lua_State* L) |
| 307 | { |
| 308 | assert (isfulluserdata (L, lua_upvalueindex (1))); |
| 309 | T* const t = Userdata::get <T> (L, 1, false); |
| 310 | MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1))); |
| 311 | assert (fnptr != 0); |
| 312 | ArgList <Params, 2> args (L); |
| 313 | FuncTraits <MemFnPtr>::call (t, fnptr, args); |
| 314 | return 0; |
| 315 | } |
| 316 | }; |
| 317 | |
| 318 | template <class MemFnPtr> |
| 319 | struct CallConstMember <MemFnPtr, void> |
| 320 | { |
| 321 | typedef typename FuncTraits <MemFnPtr>::ClassType T; |
| 322 | typedef typename FuncTraits <MemFnPtr>::Params Params; |
| 323 | |
| 324 | static int f (lua_State* L) |
| 325 | { |
| 326 | assert (isfulluserdata (L, lua_upvalueindex (1))); |
| 327 | T const* const t = Userdata::get <T> (L, 1, true); |
| 328 | MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1))); |
| 329 | assert (fnptr != 0); |
| 330 | ArgList <Params, 2> args (L); |
| 331 | FuncTraits <MemFnPtr>::call (t, fnptr, args); |
| 332 | return 0; |
| 333 | } |
| 334 | }; |
| 335 | |
| 336 | //-------------------------------------------------------------------------- |
| 337 | /** |
| 338 | lua_CFunction to call a class member lua_CFunction. |
| 339 | |
| 340 | The member function pointer is in the first upvalue. |
| 341 | The class userdata object is at the top of the Lua stack. |
| 342 | */ |
| 343 | template <class T> |
| 344 | struct CallMemberCFunction |
| 345 | { |
| 346 | static int f (lua_State* L) |
| 347 | { |
| 348 | assert (isfulluserdata (L, lua_upvalueindex (1))); |
| 349 | typedef int (T::*MFP)(lua_State* L); |
| 350 | T* const t = Userdata::get <T> (L, 1, false); |
| 351 | MFP const& fnptr = *static_cast <MFP const*> (lua_touserdata (L, lua_upvalueindex (1))); |
| 352 | assert (fnptr != 0); |
| 353 | return (t->*fnptr) (L); |
| 354 | } |
| 355 | }; |
| 356 | |
| 357 | template <class T> |
| 358 | struct CallConstMemberCFunction |
| 359 | { |
| 360 | static int f (lua_State* L) |
| 361 | { |
| 362 | assert (isfulluserdata (L, lua_upvalueindex (1))); |
| 363 | typedef int (T::*MFP)(lua_State* L); |
| 364 | T const* const t = Userdata::get <T> (L, 1, true); |
| 365 | MFP const& fnptr = *static_cast <MFP const*> (lua_touserdata (L, lua_upvalueindex (1))); |
| 366 | assert (fnptr != 0); |
| 367 | return (t->*fnptr) (L); |
| 368 | } |
| 369 | }; |
| 370 | |
| 371 | //-------------------------------------------------------------------------- |
| 372 | |
| 373 | // SFINAE Helpers |
| 374 | |
| 375 | template <class MemFnPtr, bool isConst> |
| 376 | struct CallMemberFunctionHelper |
| 377 | { |
| 378 | static void add (lua_State* L, char const* name, MemFnPtr mf) |
| 379 | { |
| 380 | new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf); |
| 381 | lua_pushcclosure (L, &CallConstMember <MemFnPtr>::f, 1); |
| 382 | lua_pushvalue (L, -1); |
| 383 | rawsetfield (L, -5, name); // const table |
| 384 | rawsetfield (L, -3, name); // class table |
| 385 | } |
| 386 | }; |
| 387 | |
| 388 | template <class MemFnPtr> |
| 389 | struct CallMemberFunctionHelper <MemFnPtr, false> |
| 390 | { |
| 391 | static void add (lua_State* L, char const* name, MemFnPtr mf) |
| 392 | { |
| 393 | new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf); |
| 394 | lua_pushcclosure (L, &CallMember <MemFnPtr>::f, 1); |
| 395 | rawsetfield (L, -3, name); // class table |
| 396 | } |
| 397 | }; |
| 398 | |
| 399 | //-------------------------------------------------------------------------- |
| 400 | /** |
| 401 | __gc metamethod for a class. |
| 402 | */ |
| 403 | template <class C> |
| 404 | static int gcMetaMethod (lua_State* L) |
| 405 | { |
| 406 | Userdata* const ud = Userdata::getExact <C> (L, 1); |
| 407 | ud->~Userdata (); |
| 408 | return 0; |
| 409 | } |
| 410 | |
| 411 | //-------------------------------------------------------------------------- |
| 412 | /** |
| 413 | lua_CFunction to get a class data member. |
| 414 | |
| 415 | The pointer-to-member is in the first upvalue. |
| 416 | The class userdata object is at the top of the Lua stack. |
| 417 | */ |
| 418 | template <class C, typename T> |
| 419 | static int getProperty (lua_State* L) |
| 420 | { |
| 421 | C const* const c = Userdata::get <C> (L, 1, true); |
| 422 | T C::** mp = static_cast <T C::**> (lua_touserdata (L, lua_upvalueindex (1))); |
| 423 | Stack <T>::push (L, c->**mp); |
| 424 | return 1; |
| 425 | } |
| 426 | |
| 427 | //-------------------------------------------------------------------------- |
| 428 | /** |
| 429 | lua_CFunction to set a class data member. |
| 430 | |
| 431 | The pointer-to-member is in the first upvalue. |
| 432 | The class userdata object is at the top of the Lua stack. |
| 433 | */ |
| 434 | template <class C, typename T> |
| 435 | static int setProperty (lua_State* L) |
| 436 | { |
| 437 | C* const c = Userdata::get <C> (L, 1, false); |
| 438 | T C::** mp = static_cast <T C::**> (lua_touserdata (L, lua_upvalueindex (1))); |
| 439 | c->**mp = Stack <T>::get (L, 2); |
| 440 | return 0; |
| 441 | } |
| 442 | }; |
trunk/3rdparty/luabridge/Source/LuaBridge/detail/FuncTraits.h
| r0 | r242832 | |
| 1 | //------------------------------------------------------------------------------ |
| 2 | /* |
| 3 | https://github.com/vinniefalco/LuaBridge |
| 4 | |
| 5 | Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com> |
| 6 | |
| 7 | License: The MIT License (http://www.opensource.org/licenses/mit-license.php) |
| 8 | |
| 9 | Permission is hereby granted, free of charge, to any person obtaining a copy |
| 10 | of this software and associated documentation files (the "Software"), to deal |
| 11 | in the Software without restriction, including without limitation the rights |
| 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| 13 | copies of the Software, and to permit persons to whom the Software is |
| 14 | furnished to do so, subject to the following conditions: |
| 15 | |
| 16 | The above copyright notice and this permission notice shall be included in all |
| 17 | copies or substantial portions of the Software. |
| 18 | |
| 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| 25 | SOFTWARE. |
| 26 | */ |
| 27 | //============================================================================== |
| 28 | |
| 29 | /** |
| 30 | Since the throw specification is part of a function signature, the FuncTraits |
| 31 | family of templates needs to be specialized for both types. The |
| 32 | LUABRIDGE_THROWSPEC macro controls whether we use the 'throw ()' form, or |
| 33 | 'noexcept' (if C++11 is available) to distinguish the functions. |
| 34 | */ |
| 35 | #if defined (__APPLE_CPP__) || defined(__APPLE_CC__) || defined(__clang__) || defined(__GNUC__) || \ |
| 36 | (defined (_MSC_VER) && (_MSC_VER >= 1700)) |
| 37 | // Do not define LUABRIDGE_THROWSPEC since the Xcode and gcc compilers do not |
| 38 | // distinguish the throw specification in the function signature. |
| 39 | #else |
| 40 | // Visual Studio 10 and earlier pay too much mind to useless throw() spec. |
| 41 | // |
| 42 | # define LUABRIDGE_THROWSPEC throw() |
| 43 | #endif |
| 44 | |
| 45 | //============================================================================== |
| 46 | /** |
| 47 | Traits for function pointers. |
| 48 | |
| 49 | There are three types of functions: global, non-const member, and const |
| 50 | member. These templates determine the type of function, which class type it |
| 51 | belongs to if it is a class member, the const-ness if it is a member |
| 52 | function, and the type information for the return value and argument list. |
| 53 | |
| 54 | Expansions are provided for functions with up to 8 parameters. This can be |
| 55 | manually extended, or expanded to an arbitrary amount using C++11 features. |
| 56 | */ |
| 57 | template <class MemFn, class D = MemFn> |
| 58 | struct FuncTraits |
| 59 | { |
| 60 | }; |
| 61 | |
| 62 | /* Ordinary function pointers. */ |
| 63 | |
| 64 | template <class R, class D> |
| 65 | struct FuncTraits <R (*) (), D> |
| 66 | { |
| 67 | static bool const isMemberFunction = false; |
| 68 | typedef D DeclType; |
| 69 | typedef R ReturnType; |
| 70 | typedef None Params; |
| 71 | static R call (D fp, TypeListValues <Params>) |
| 72 | { |
| 73 | return fp (); |
| 74 | } |
| 75 | }; |
| 76 | |
| 77 | template <class R, class P1, class D> |
| 78 | struct FuncTraits <R (*) (P1), D> |
| 79 | { |
| 80 | static bool const isMemberFunction = false; |
| 81 | typedef D DeclType; |
| 82 | typedef R ReturnType; |
| 83 | typedef TypeList <P1> Params; |
| 84 | static R call (D fp, TypeListValues <Params> tvl) |
| 85 | { |
| 86 | return fp (tvl.hd); |
| 87 | } |
| 88 | }; |
| 89 | |
| 90 | template <class R, class P1, class P2, class D> |
| 91 | struct FuncTraits <R (*) (P1, P2), D> |
| 92 | { |
| 93 | static bool const isMemberFunction = false; |
| 94 | typedef D DeclType; |
| 95 | typedef R ReturnType; |
| 96 | typedef TypeList <P1, TypeList <P2> > Params; |
| 97 | static R call (D fp, TypeListValues <Params> tvl) |
| 98 | { |
| 99 | return fp (tvl.hd, tvl.tl.hd); |
| 100 | } |
| 101 | }; |
| 102 | |
| 103 | template <class R, class P1, class P2, class P3, class D> |
| 104 | struct FuncTraits <R (*) (P1, P2, P3), D> |
| 105 | { |
| 106 | static bool const isMemberFunction = false; |
| 107 | typedef D DeclType; |
| 108 | typedef R ReturnType; |
| 109 | typedef TypeList <P1, TypeList <P2, TypeList <P3> > > Params; |
| 110 | static R call (D fp, TypeListValues <Params> tvl) |
| 111 | { |
| 112 | return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd); |
| 113 | } |
| 114 | }; |
| 115 | |
| 116 | template <class R, class P1, class P2, class P3, class P4, class D> |
| 117 | struct FuncTraits <R (*) (P1, P2, P3, P4), D> |
| 118 | { |
| 119 | static bool const isMemberFunction = false; |
| 120 | typedef D DeclType; |
| 121 | typedef R ReturnType; |
| 122 | typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4> > > > Params; |
| 123 | static R call (D fp, TypeListValues <Params> tvl) |
| 124 | { |
| 125 | return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd); |
| 126 | } |
| 127 | }; |
| 128 | |
| 129 | template <class R, class P1, class P2, class P3, class P4, class P5, class D> |
| 130 | struct FuncTraits <R (*) (P1, P2, P3, P4, P5), D> |
| 131 | { |
| 132 | static bool const isMemberFunction = false; |
| 133 | typedef D DeclType; |
| 134 | typedef R ReturnType; |
| 135 | typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5> > > > > Params; |
| 136 | static R call (D fp, TypeListValues <Params> tvl) |
| 137 | { |
| 138 | return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd); |
| 139 | } |
| 140 | }; |
| 141 | |
| 142 | template <class R, class P1, class P2, class P3, class P4, class P5, class P6, class D> |
| 143 | struct FuncTraits <R (*) (P1, P2, P3, P4, P5, P6), D> |
| 144 | { |
| 145 | static bool const isMemberFunction = false; |
| 146 | typedef D DeclType; |
| 147 | typedef R ReturnType; |
| 148 | typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6> > > > > > Params; |
| 149 | static R call (D fp, TypeListValues <Params> tvl) |
| 150 | { |
| 151 | return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd); |
| 152 | } |
| 153 | }; |
| 154 | |
| 155 | template <class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class D> |
| 156 | struct FuncTraits <R (*) (P1, P2, P3, P4, P5, P6, P7), D> |
| 157 | { |
| 158 | static bool const isMemberFunction = false; |
| 159 | typedef D DeclType; |
| 160 | typedef R ReturnType; |
| 161 | typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7> > > > > > > Params; |
| 162 | static R call (D fp, TypeListValues <Params> tvl) |
| 163 | { |
| 164 | return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd); |
| 165 | } |
| 166 | }; |
| 167 | |
| 168 | template <class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class D> |
| 169 | struct FuncTraits <R (*) (P1, P2, P3, P4, P5, P6, P7, P8), D> |
| 170 | { |
| 171 | static bool const isMemberFunction = false; |
| 172 | typedef D DeclType; |
| 173 | typedef R ReturnType; |
| 174 | typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7, TypeList <P8> > > > > > > > Params; |
| 175 | static R call (D fp, TypeListValues <Params> tvl) |
| 176 | { |
| 177 | return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd); |
| 178 | } |
| 179 | }; |
| 180 | |
| 181 | /* Non-const member function pointers. */ |
| 182 | |
| 183 | template <class T, class R, class D> |
| 184 | struct FuncTraits <R (T::*) (), D> |
| 185 | { |
| 186 | static bool const isMemberFunction = true; |
| 187 | static bool const isConstMemberFunction = false; |
| 188 | typedef D DeclType; |
| 189 | typedef T ClassType; |
| 190 | typedef R ReturnType; |
| 191 | typedef None Params; |
| 192 | static R call (T* obj, D fp, TypeListValues <Params>) |
| 193 | { |
| 194 | return (obj->*fp)(); |
| 195 | } |
| 196 | }; |
| 197 | |
| 198 | template <class T, class R, class P1, class D> |
| 199 | struct FuncTraits <R (T::*) (P1), D> |
| 200 | { |
| 201 | static bool const isMemberFunction = true; |
| 202 | static bool const isConstMemberFunction = false; |
| 203 | typedef D DeclType; |
| 204 | typedef T ClassType; |
| 205 | typedef R ReturnType; |
| 206 | typedef TypeList <P1> Params; |
| 207 | static R call (T* obj, D fp, TypeListValues <Params> tvl) |
| 208 | { |
| 209 | return (obj->*fp)(tvl.hd); |
| 210 | } |
| 211 | }; |
| 212 | |
| 213 | template <class T, class R, class P1, class P2, class D> |
| 214 | struct FuncTraits <R (T::*) (P1, P2), D> |
| 215 | { |
| 216 | static bool const isMemberFunction = true; |
| 217 | static bool const isConstMemberFunction = false; |
| 218 | typedef D DeclType; |
| 219 | typedef T ClassType; |
| 220 | typedef R ReturnType; |
| 221 | typedef TypeList <P1, TypeList <P2> > Params; |
| 222 | static R call (T* obj, D fp, TypeListValues <Params> tvl) |
| 223 | { |
| 224 | return (obj->*fp)(tvl.hd, tvl.tl.hd); |
| 225 | } |
| 226 | }; |
| 227 | |
| 228 | template <class T, class R, class P1, class P2, class P3, class D> |
| 229 | struct FuncTraits <R (T::*) (P1, P2, P3), D> |
| 230 | { |
| 231 | static bool const isMemberFunction = true; |
| 232 | static bool const isConstMemberFunction = false; |
| 233 | typedef D DeclType; |
| 234 | typedef T ClassType; |
| 235 | typedef R ReturnType; |
| 236 | typedef TypeList <P1, TypeList <P2, TypeList <P3> > > Params; |
| 237 | static R call (T* obj, D fp, TypeListValues <Params> tvl) |
| 238 | { |
| 239 | return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd); |
| 240 | } |
| 241 | }; |
| 242 | |
| 243 | template <class T, class R, class P1, class P2, class P3, class P4, class D> |
| 244 | struct FuncTraits <R (T::*) (P1, P2, P3, P4), D> |
| 245 | { |
| 246 | static bool const isMemberFunction = true; |
| 247 | static bool const isConstMemberFunction = false; |
| 248 | typedef D DeclType; |
| 249 | typedef T ClassType; |
| 250 | typedef R ReturnType; |
| 251 | typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4> > > > Params; |
| 252 | static R call (T* obj, D fp, TypeListValues <Params> tvl) |
| 253 | { |
| 254 | return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd); |
| 255 | } |
| 256 | }; |
| 257 | |
| 258 | template <class T, class R, class P1, class P2, class P3, class P4, class P5, class D> |
| 259 | struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5), D> |
| 260 | { |
| 261 | static bool const isMemberFunction = true; |
| 262 | static bool const isConstMemberFunction = false; |
| 263 | typedef D DeclType; |
| 264 | typedef T ClassType; |
| 265 | typedef R ReturnType; |
| 266 | typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5> > > > > Params; |
| 267 | static R call (T* obj, D fp, TypeListValues <Params> tvl) |
| 268 | { |
| 269 | return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd); |
| 270 | } |
| 271 | }; |
| 272 | |
| 273 | template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class D> |
| 274 | struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6), D> |
| 275 | { |
| 276 | static bool const isMemberFunction = true; |
| 277 | static bool const isConstMemberFunction = false; |
| 278 | typedef D DeclType; |
| 279 | typedef T ClassType; |
| 280 | typedef R ReturnType; |
| 281 | typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6> > > > > > Params; |
| 282 | static R call (T* obj, D fp, TypeListValues <Params> tvl) |
| 283 | { |
| 284 | return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd); |
| 285 | } |
| 286 | }; |
| 287 | |
| 288 | template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class D> |
| 289 | struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6, P7), D> |
| 290 | { |
| 291 | static bool const isMemberFunction = true; |
| 292 | static bool const isConstMemberFunction = false; |
| 293 | typedef D DeclType; |
| 294 | typedef T ClassType; |
| 295 | typedef R ReturnType; |
| 296 | typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7> > > > > > > Params; |
| 297 | static R call (T* obj, D fp, TypeListValues <Params> tvl) |
| 298 | { |
| 299 | return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd); |
| 300 | } |
| 301 | }; |
| 302 | |
| 303 | template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class D> |
| 304 | struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6, P7, P8), D> |
| 305 | { |
| 306 | static bool const isMemberFunction = true; |
| 307 | static bool const isConstMemberFunction = false; |
| 308 | typedef D DeclType; |
| 309 | typedef T ClassType; |
| 310 | typedef R ReturnType; |
| 311 | typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7, TypeList <P8> > > > > > > > Params; |
| 312 | static R call (T* obj, D fp, TypeListValues <Params> tvl) |
| 313 | { |
| 314 | return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd); |
| 315 | } |
| 316 | }; |
| 317 | |
| 318 | /* Const member function pointers. */ |
| 319 | |
| 320 | template <class T, class R, class D> |
| 321 | struct FuncTraits <R (T::*) () const, D> |
| 322 | { |
| 323 | static bool const isMemberFunction = true; |
| 324 | static bool const isConstMemberFunction = true; |
| 325 | typedef D DeclType; |
| 326 | typedef T ClassType; |
| 327 | typedef R ReturnType; |
| 328 | typedef None Params; |
| 329 | static R call (T const* obj, D fp, TypeListValues <Params>) |
| 330 | { |
| 331 | return (obj->*fp)(); |
| 332 | } |
| 333 | }; |
| 334 | |
| 335 | template <class T, class R, class P1, class D> |
| 336 | struct FuncTraits <R (T::*) (P1) const, D> |
| 337 | { |
| 338 | static bool const isMemberFunction = true; |
| 339 | static bool const isConstMemberFunction = true; |
| 340 | typedef D DeclType; |
| 341 | typedef T ClassType; |
| 342 | typedef R ReturnType; |
| 343 | typedef TypeList <P1> Params; |
| 344 | static R call (T const* obj, D fp, TypeListValues <Params> tvl) |
| 345 | { |
| 346 | return (obj->*fp)(tvl.hd); |
| 347 | } |
| 348 | }; |
| 349 | |
| 350 | template <class T, class R, class P1, class P2, class D> |
| 351 | struct FuncTraits <R (T::*) (P1, P2) const, D> |
| 352 | { |
| 353 | static bool const isMemberFunction = true; |
| 354 | static bool const isConstMemberFunction = true; |
| 355 | typedef D DeclType; |
| 356 | typedef T ClassType; |
| 357 | typedef R ReturnType; |
| 358 | typedef TypeList <P1, TypeList <P2> > Params; |
| 359 | static R call (T const* obj, R (T::*fp) (P1, P2) const, |
| 360 | TypeListValues <Params> tvl) |
| 361 | { |
| 362 | return (obj->*fp)(tvl.hd, tvl.tl.hd); |
| 363 | } |
| 364 | }; |
| 365 | |
| 366 | template <class T, class R, class P1, class P2, class P3, class D> |
| 367 | struct FuncTraits <R (T::*) (P1, P2, P3) const, D> |
| 368 | { |
| 369 | static bool const isMemberFunction = true; |
| 370 | static bool const isConstMemberFunction = true; |
| 371 | typedef D DeclType; |
| 372 | typedef T ClassType; |
| 373 | typedef R ReturnType; |
| 374 | typedef TypeList <P1, TypeList <P2, TypeList <P3> > > Params; |
| 375 | static R call (T const* obj, D fp, TypeListValues <Params> tvl) |
| 376 | { |
| 377 | return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd); |
| 378 | } |
| 379 | }; |
| 380 | |
| 381 | template <class T, class R, class P1, class P2, class P3, class P4, class D> |
| 382 | struct FuncTraits <R (T::*) (P1, P2, P3, P4) const, D> |
| 383 | { |
| 384 | static bool const isMemberFunction = true; |
| 385 | static bool const isConstMemberFunction = true; |
| 386 | typedef D DeclType; |
| 387 | typedef T ClassType; |
| 388 | typedef R ReturnType; |
| 389 | typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4> > > > Params; |
| 390 | static R call (T const* obj, D fp, TypeListValues <Params> tvl) |
| 391 | { |
| 392 | return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd); |
| 393 | } |
| 394 | }; |
| 395 | |
| 396 | template <class T, class R, class P1, class P2, class P3, class P4, class P5, class D> |
| 397 | struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5) const, D> |
| 398 | { |
| 399 | static bool const isMemberFunction = true; |
| 400 | static bool const isConstMemberFunction = true; |
| 401 | typedef D DeclType; |
| 402 | typedef T ClassType; |
| 403 | typedef R ReturnType; |
| 404 | typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5> > > > > Params; |
| 405 | static R call (T const* obj, D fp, TypeListValues <Params> tvl) |
| 406 | { |
| 407 | return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd); |
| 408 | } |
| 409 | }; |
| 410 | |
| 411 | template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class D> |
| 412 | struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6) const, D> |
| 413 | { |
| 414 | static bool const isMemberFunction = true; |
| 415 | static bool const isConstMemberFunction = true; |
| 416 | typedef D DeclType; |
| 417 | typedef T ClassType; |
| 418 | typedef R ReturnType; |
| 419 | typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6> > > > > > Params; |
| 420 | static R call (T const* obj, D fp, TypeListValues <Params> tvl) |
| 421 | { |
| 422 | return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd); |
| 423 | } |
| 424 | }; |
| 425 | |
| 426 | template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class D> |
| 427 | struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6, P7) const, D> |
| 428 | { |
| 429 | static bool const isMemberFunction = true; |
| 430 | static bool const isConstMemberFunction = true; |
| 431 | typedef D DeclType; |
| 432 | typedef T ClassType; |
| 433 | typedef R ReturnType; |
| 434 | typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7> > > > > > > Params; |
| 435 | static R call (T const* obj, D fp, TypeListValues <Params> tvl) |
| 436 | { |
| 437 | return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd); |
| 438 | } |
| 439 | }; |
| 440 | |
| 441 | template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class D> |
| 442 | struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6, P7, P8) const, D> |
| 443 | { |
| 444 | static bool const isMemberFunction = true; |
| 445 | static bool const isConstMemberFunction = true; |
| 446 | typedef D DeclType; |
| 447 | typedef T ClassType; |
| 448 | typedef R ReturnType; |
| 449 | typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7, TypeList <P8> > > > > > > > Params; |
| 450 | static R call (T const* obj, D fp, TypeListValues <Params> tvl) |
| 451 | { |
| 452 | return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd); |
| 453 | } |
| 454 | }; |
| 455 | |
| 456 | #if defined (LUABRIDGE_THROWSPEC) |
| 457 | |
| 458 | /* Ordinary function pointers. */ |
| 459 | |
| 460 | template <class R, class D> |
| 461 | struct FuncTraits <R (*) () LUABRIDGE_THROWSPEC, D> |
| 462 | { |
| 463 | static bool const isMemberFunction = false; |
| 464 | typedef D DeclType; |
| 465 | typedef R ReturnType; |
| 466 | typedef None Params; |
| 467 | static R call (D fp, TypeListValues <Params> const&) |
| 468 | { |
| 469 | return fp (); |
| 470 | } |
| 471 | }; |
| 472 | |
| 473 | template <class R, class P1, class D> |
| 474 | struct FuncTraits <R (*) (P1) LUABRIDGE_THROWSPEC, D> |
| 475 | { |
| 476 | static bool const isMemberFunction = false; |
| 477 | typedef D DeclType; |
| 478 | typedef R ReturnType; |
| 479 | typedef TypeList <P1> Params; |
| 480 | static R call (D fp, TypeListValues <Params> tvl) |
| 481 | { |
| 482 | return fp (tvl.hd); |
| 483 | } |
| 484 | }; |
| 485 | |
| 486 | template <class R, class P1, class P2, class D> |
| 487 | struct FuncTraits <R (*) (P1, P2) LUABRIDGE_THROWSPEC, D> |
| 488 | { |
| 489 | static bool const isMemberFunction = false; |
| 490 | typedef D DeclType; |
| 491 | typedef R ReturnType; |
| 492 | typedef TypeList <P1, TypeList <P2> > Params; |
| 493 | static R call (D fp, TypeListValues <Params> tvl) |
| 494 | { |
| 495 | return fp (tvl.hd, tvl.tl.hd); |
| 496 | } |
| 497 | }; |
| 498 | |
| 499 | template <class R, class P1, class P2, class P3, class D> |
| 500 | struct FuncTraits <R (*) (P1, P2, P3) LUABRIDGE_THROWSPEC, D> |
| 501 | { |
| 502 | static bool const isMemberFunction = false; |
| 503 | typedef D DeclType; |
| 504 | typedef R ReturnType; |
| 505 | typedef TypeList <P1, TypeList <P2, TypeList <P3> > > Params; |
| 506 | static R call (D fp, TypeListValues <Params> tvl) |
| 507 | { |
| 508 | return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd); |
| 509 | } |
| 510 | }; |
| 511 | |
| 512 | template <class R, class P1, class P2, class P3, class P4, class D> |
| 513 | struct FuncTraits <R (*) (P1, P2, P3, P4) LUABRIDGE_THROWSPEC, D> |
| 514 | { |
| 515 | static bool const isMemberFunction = false; |
| 516 | typedef D DeclType; |
| 517 | typedef R ReturnType; |
| 518 | typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4> > > > Params; |
| 519 | static R call (D fp, TypeListValues <Params> tvl) |
| 520 | { |
| 521 | return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd); |
| 522 | } |
| 523 | }; |
| 524 | |
| 525 | template <class R, class P1, class P2, class P3, class P4, class P5, class D> |
| 526 | struct FuncTraits <R (*) (P1, P2, P3, P4, P5) LUABRIDGE_THROWSPEC, D> |
| 527 | { |
| 528 | static bool const isMemberFunction = false; |
| 529 | typedef D DeclType; |
| 530 | typedef R ReturnType; |
| 531 | typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5> > > > > Params; |
| 532 | static R call (D fp, TypeListValues <Params> tvl) |
| 533 | { |
| 534 | return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd); |
| 535 | } |
| 536 | }; |
| 537 | |
| 538 | template <class R, class P1, class P2, class P3, class P4, class P5, class P6, class D> |
| 539 | struct FuncTraits <R (*) (P1, P2, P3, P4, P5, P6) LUABRIDGE_THROWSPEC, D> |
| 540 | { |
| 541 | static bool const isMemberFunction = false; |
| 542 | typedef D DeclType; |
| 543 | typedef R ReturnType; |
| 544 | typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6> > > > > > Params; |
| 545 | static R call (D fp, TypeListValues <Params> tvl) |
| 546 | { |
| 547 | return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd); |
| 548 | } |
| 549 | }; |
| 550 | |
| 551 | template <class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class D> |
| 552 | struct FuncTraits <R (*) (P1, P2, P3, P4, P5, P6, P7) LUABRIDGE_THROWSPEC, D> |
| 553 | { |
| 554 | static bool const isMemberFunction = false; |
| 555 | typedef D DeclType; |
| 556 | typedef R ReturnType; |
| 557 | typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7> > > > > > > Params; |
| 558 | static R call (D fp, TypeListValues <Params> tvl) |
| 559 | { |
| 560 | return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd); |
| 561 | } |
| 562 | }; |
| 563 | |
| 564 | template <class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class D> |
| 565 | struct FuncTraits <R (*) (P1, P2, P3, P4, P5, P6, P7, P8) LUABRIDGE_THROWSPEC, D> |
| 566 | { |
| 567 | static bool const isMemberFunction = false; |
| 568 | typedef D DeclType; |
| 569 | typedef R ReturnType; |
| 570 | typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7, TypeList <P8> > > > > > > > Params; |
| 571 | static R call (D fp, TypeListValues <Params> tvl) |
| 572 | { |
| 573 | return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd); |
| 574 | } |
| 575 | }; |
| 576 | |
| 577 | /* Non-const member function pointers with THROWSPEC. */ |
| 578 | |
| 579 | template <class T, class R, class D> |
| 580 | struct FuncTraits <R (T::*) () LUABRIDGE_THROWSPEC, D> |
| 581 | { |
| 582 | static bool const isMemberFunction = true; |
| 583 | static bool const isConstMemberFunction = false; |
| 584 | typedef D DeclType; |
| 585 | typedef T ClassType; |
| 586 | typedef R ReturnType; |
| 587 | typedef None Params; |
| 588 | static R call (T* obj, D fp, TypeListValues <Params> const&) |
| 589 | { |
| 590 | return (obj->*fp)(); |
| 591 | } |
| 592 | }; |
| 593 | |
| 594 | template <class T, class R, class P1, class D> |
| 595 | struct FuncTraits <R (T::*) (P1) LUABRIDGE_THROWSPEC, D> |
| 596 | { |
| 597 | static bool const isMemberFunction = true; |
| 598 | static bool const isConstMemberFunction = false; |
| 599 | typedef D DeclType; |
| 600 | typedef T ClassType; |
| 601 | typedef R ReturnType; |
| 602 | typedef TypeList <P1> Params; |
| 603 | static R call (T* obj, D fp, TypeListValues <Params> tvl) |
| 604 | { |
| 605 | return (obj->*fp)(tvl.hd); |
| 606 | } |
| 607 | }; |
| 608 | |
| 609 | template <class T, class R, class P1, class P2, class D> |
| 610 | struct FuncTraits <R (T::*) (P1, P2) LUABRIDGE_THROWSPEC, D> |
| 611 | { |
| 612 | static bool const isMemberFunction = true; |
| 613 | static bool const isConstMemberFunction = false; |
| 614 | typedef D DeclType; |
| 615 | typedef T ClassType; |
| 616 | typedef R ReturnType; |
| 617 | typedef TypeList <P1, TypeList <P2> > Params; |
| 618 | static R call (T* obj, D fp, TypeListValues <Params> tvl) |
| 619 | { |
| 620 | return (obj->*fp)(tvl.hd, tvl.tl.hd); |
| 621 | } |
| 622 | }; |
| 623 | |
| 624 | template <class T, class R, class P1, class P2, class P3, class D> |
| 625 | struct FuncTraits <R (T::*) (P1, P2, P3) LUABRIDGE_THROWSPEC, D> |
| 626 | { |
| 627 | static bool const isMemberFunction = true; |
| 628 | static bool const isConstMemberFunction = false; |
| 629 | typedef D DeclType; |
| 630 | typedef T ClassType; |
| 631 | typedef R ReturnType; |
| 632 | typedef TypeList <P1, TypeList <P2, TypeList <P3> > > Params; |
| 633 | static R call (T* obj, D fp, TypeListValues <Params> tvl) |
| 634 | { |
| 635 | return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd); |
| 636 | } |
| 637 | }; |
| 638 | |
| 639 | template <class T, class R, class P1, class P2, class P3, class P4, class D> |
| 640 | struct FuncTraits <R (T::*) (P1, P2, P3, P4) LUABRIDGE_THROWSPEC, D> |
| 641 | { |
| 642 | static bool const isMemberFunction = true; |
| 643 | static bool const isConstMemberFunction = false; |
| 644 | typedef D DeclType; |
| 645 | typedef T ClassType; |
| 646 | typedef R ReturnType; |
| 647 | typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4> > > > Params; |
| 648 | static R call (T* obj, D fp, TypeListValues <Params> tvl) |
| 649 | { |
| 650 | return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd); |
| 651 | } |
| 652 | }; |
| 653 | |
| 654 | template <class T, class R, class P1, class P2, class P3, class P4, class P5, class D> |
| 655 | struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5) LUABRIDGE_THROWSPEC, D> |
| 656 | { |
| 657 | static bool const isMemberFunction = true; |
| 658 | static bool const isConstMemberFunction = false; |
| 659 | typedef D DeclType; |
| 660 | typedef T ClassType; |
| 661 | typedef R ReturnType; |
| 662 | typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5> > > > > Params; |
| 663 | static R call (T* obj, D fp, TypeListValues <Params> tvl) |
| 664 | { |
| 665 | return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd); |
| 666 | } |
| 667 | }; |
| 668 | |
| 669 | template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class D> |
| 670 | struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6) LUABRIDGE_THROWSPEC, D> |
| 671 | { |
| 672 | static bool const isMemberFunction = true; |
| 673 | static bool const isConstMemberFunction = false; |
| 674 | typedef D DeclType; |
| 675 | typedef T ClassType; |
| 676 | typedef R ReturnType; |
| 677 | typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6> > > > > > Params; |
| 678 | static R call (T* obj, D fp, TypeListValues <Params> tvl) |
| 679 | { |
| 680 | return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd); |
| 681 | } |
| 682 | }; |
| 683 | |
| 684 | template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class D> |
| 685 | struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6, P7) LUABRIDGE_THROWSPEC, D> |
| 686 | { |
| 687 | static bool const isMemberFunction = true; |
| 688 | static bool const isConstMemberFunction = false; |
| 689 | typedef D DeclType; |
| 690 | typedef T ClassType; |
| 691 | typedef R ReturnType; |
| 692 | typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7> > > > > > > Params; |
| 693 | static R call (T* obj, D fp, TypeListValues <Params> tvl) |
| 694 | { |
| 695 | return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd); |
| 696 | } |
| 697 | }; |
| 698 | |
| 699 | template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class D> |
| 700 | struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6, P7, P8) LUABRIDGE_THROWSPEC, D> |
| 701 | { |
| 702 | static bool const isMemberFunction = true; |
| 703 | static bool const isConstMemberFunction = false; |
| 704 | typedef D DeclType; |
| 705 | typedef T ClassType; |
| 706 | typedef R ReturnType; |
| 707 | typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7, TypeList <P8> > > > > > > > Params; |
| 708 | static R call (T* obj, D fp, TypeListValues <Params> tvl) |
| 709 | { |
| 710 | return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd); |
| 711 | } |
| 712 | }; |
| 713 | |
| 714 | /* Const member function pointers with THROWSPEC. */ |
| 715 | |
| 716 | template <class T, class R, class D> |
| 717 | struct FuncTraits <R (T::*) () const LUABRIDGE_THROWSPEC, D> |
| 718 | { |
| 719 | static bool const isMemberFunction = true; |
| 720 | static bool const isConstMemberFunction = true; |
| 721 | typedef D DeclType; |
| 722 | typedef T ClassType; |
| 723 | typedef R ReturnType; |
| 724 | typedef None Params; |
| 725 | static R call (T const* obj, D fp, TypeListValues <Params>) |
| 726 | { |
| 727 | return (obj->*fp)(); |
| 728 | } |
| 729 | }; |
| 730 | |
| 731 | template <class T, class R, class P1, class D> |
| 732 | struct FuncTraits <R (T::*) (P1) const LUABRIDGE_THROWSPEC, D> |
| 733 | { |
| 734 | static bool const isMemberFunction = true; |
| 735 | static bool const isConstMemberFunction = true; |
| 736 | typedef D DeclType; |
| 737 | typedef T ClassType; |
| 738 | typedef R ReturnType; |
| 739 | typedef TypeList <P1> Params; |
| 740 | static R call (T const* obj, D fp, TypeListValues <Params> tvl) |
| 741 | { |
| 742 | return (obj->*fp)(tvl.hd); |
| 743 | } |
| 744 | }; |
| 745 | |
| 746 | template <class T, class R, class P1, class P2, class D> |
| 747 | struct FuncTraits <R (T::*) (P1, P2) const LUABRIDGE_THROWSPEC, D> |
| 748 | { |
| 749 | static bool const isMemberFunction = true; |
| 750 | static bool const isConstMemberFunction = true; |
| 751 | typedef D DeclType; |
| 752 | typedef T ClassType; |
| 753 | typedef R ReturnType; |
| 754 | typedef TypeList <P1, TypeList <P2> > Params; |
| 755 | static R call (T const* obj, D fp, TypeListValues <Params> tvl) |
| 756 | { |
| 757 | return (obj->*fp)(tvl.hd, tvl.tl.hd); |
| 758 | } |
| 759 | }; |
| 760 | |
| 761 | template <class T, class R, class P1, class P2, class P3, class D> |
| 762 | struct FuncTraits <R (T::*) (P1, P2, P3) const LUABRIDGE_THROWSPEC, D> |
| 763 | { |
| 764 | static bool const isMemberFunction = true; |
| 765 | static bool const isConstMemberFunction = true; |
| 766 | typedef D DeclType; |
| 767 | typedef T ClassType; |
| 768 | typedef R ReturnType; |
| 769 | typedef TypeList <P1, TypeList <P2, TypeList <P3> > > Params; |
| 770 | static R call (T const* obj, D fp, TypeListValues <Params> tvl) |
| 771 | { |
| 772 | return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd); |
| 773 | } |
| 774 | }; |
| 775 | |
| 776 | template <class T, class R, class P1, class P2, class P3, class P4, class D> |
| 777 | struct FuncTraits <R (T::*) (P1, P2, P3, P4) const LUABRIDGE_THROWSPEC, D> |
| 778 | { |
| 779 | static bool const isMemberFunction = true; |
| 780 | static bool const isConstMemberFunction = true; |
| 781 | typedef D DeclType; |
| 782 | typedef T ClassType; |
| 783 | typedef R ReturnType; |
| 784 | typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4> > > > Params; |
| 785 | static R call (T const* obj, D fp, TypeListValues <Params> tvl) |
| 786 | { |
| 787 | return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd); |
| 788 | } |
| 789 | }; |
| 790 | |
| 791 | template <class T, class R, class P1, class P2, class P3, class P4, class P5, class D> |
| 792 | struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5) const LUABRIDGE_THROWSPEC, D> |
| 793 | { |
| 794 | static bool const isMemberFunction = true; |
| 795 | static bool const isConstMemberFunction = true; |
| 796 | typedef D DeclType; |
| 797 | typedef T ClassType; |
| 798 | typedef R ReturnType; |
| 799 | typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5> > > > > Params; |
| 800 | static R call (T const* obj, D fp, TypeListValues <Params> tvl) |
| 801 | { |
| 802 | return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, |
| 803 | tvl.tl.tl.tl.tl.hd); |
| 804 | } |
| 805 | }; |
| 806 | |
| 807 | template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class D> |
| 808 | struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6) const LUABRIDGE_THROWSPEC, D> |
| 809 | { |
| 810 | static bool const isMemberFunction = true; |
| 811 | static bool const isConstMemberFunction = true; |
| 812 | typedef D DeclType; |
| 813 | typedef T ClassType; |
| 814 | typedef R ReturnType; |
| 815 | typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6> > > > > > Params; |
| 816 | static R call (T const* obj, D fp, TypeListValues <Params> tvl) |
| 817 | { |
| 818 | return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd); |
| 819 | } |
| 820 | }; |
| 821 | |
| 822 | template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class D> |
| 823 | struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6, P7) const LUABRIDGE_THROWSPEC, D> |
| 824 | { |
| 825 | static bool const isMemberFunction = true; |
| 826 | static bool const isConstMemberFunction = true; |
| 827 | typedef D DeclType; |
| 828 | typedef T ClassType; |
| 829 | typedef R ReturnType; |
| 830 | typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7> > > > > > > Params; |
| 831 | static R call (T const* obj, D fp, TypeListValues <Params> tvl) |
| 832 | { |
| 833 | return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd); |
| 834 | } |
| 835 | }; |
| 836 | |
| 837 | template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class D> |
| 838 | struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6, P7, P8) const LUABRIDGE_THROWSPEC, D> |
| 839 | { |
| 840 | static bool const isMemberFunction = true; |
| 841 | static bool const isConstMemberFunction = true; |
| 842 | typedef D DeclType; |
| 843 | typedef T ClassType; |
| 844 | typedef R ReturnType; |
| 845 | typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7, TypeList <P8> > > > > > > > Params; |
| 846 | static R call (T const* obj, D fp, TypeListValues <Params> tvl) |
| 847 | { |
| 848 | return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd); |
| 849 | } |
| 850 | }; |
| 851 | |
| 852 | #endif |
trunk/3rdparty/luabridge/Source/LuaBridge/detail/LuaRef.h
| r0 | r242832 | |
| 1 | //------------------------------------------------------------------------------ |
| 2 | /* |
| 3 | https://github.com/vinniefalco/LuaBridge |
| 4 | |
| 5 | Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com> |
| 6 | Copyright 2008, Nigel Atkinson <suprapilot+LuaCode@gmail.com> |
| 7 | |
| 8 | License: The MIT License (http://www.opensource.org/licenses/mit-license.php) |
| 9 | |
| 10 | Permission is hereby granted, free of charge, to any person obtaining a copy |
| 11 | of this software and associated documentation files (the "Software"), to deal |
| 12 | in the Software without restriction, including without limitation the rights |
| 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| 14 | copies of the Software, and to permit persons to whom the Software is |
| 15 | furnished to do so, subject to the following conditions: |
| 16 | |
| 17 | The above copyright notice and this permission notice shall be included in all |
| 18 | copies or substantial portions of the Software. |
| 19 | |
| 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| 26 | SOFTWARE. |
| 27 | */ |
| 28 | //============================================================================== |
| 29 | |
| 30 | //------------------------------------------------------------------------------ |
| 31 | /** |
| 32 | Type tag for representing LUA_TNIL. |
| 33 | |
| 34 | Construct one of these using `Nil()` to represent a Lua nil. This is faster |
| 35 | than creating a reference in the registry to nil. Example: |
| 36 | |
| 37 | LuaRef t (LuaRef::createTable (L)); |
| 38 | ... |
| 39 | t ["k"] = Nil(); // assign nil |
| 40 | */ |
| 41 | struct Nil |
| 42 | { |
| 43 | }; |
| 44 | |
| 45 | //------------------------------------------------------------------------------ |
| 46 | /** |
| 47 | Lightweight reference to a Lua object. |
| 48 | |
| 49 | The reference is maintained for the lifetime of the C++ object. |
| 50 | */ |
| 51 | class LuaRef |
| 52 | { |
| 53 | private: |
| 54 | class Proxy; |
| 55 | friend struct Stack <Proxy>; |
| 56 | |
| 57 | //---------------------------------------------------------------------------- |
| 58 | /** |
| 59 | Pop the Lua stack. |
| 60 | |
| 61 | Pops the specified number of stack items on destruction. We use this |
| 62 | when returning objects, to avoid an explicit temporary variable, since |
| 63 | the destructor executes after the return statement. For example: |
| 64 | |
| 65 | template <class U> |
| 66 | U cast (lua_State* L) |
| 67 | { |
| 68 | StackPop p (L, 1); |
| 69 | ... |
| 70 | return U (); // dtor called after this line |
| 71 | } |
| 72 | |
| 73 | @note The `StackPop` object must always be a named local variable. |
| 74 | */ |
| 75 | class StackPop |
| 76 | { |
| 77 | public: |
| 78 | /** Create a StackPop object. |
| 79 | |
| 80 | @param count The number of stack entries to pop on destruction. |
| 81 | */ |
| 82 | StackPop (lua_State* L, int count) |
| 83 | : m_L (L) |
| 84 | , m_count (count) |
| 85 | { |
| 86 | } |
| 87 | |
| 88 | ~StackPop () |
| 89 | { |
| 90 | lua_pop (m_L, m_count); |
| 91 | } |
| 92 | |
| 93 | private: |
| 94 | lua_State* m_L; |
| 95 | int m_count; |
| 96 | }; |
| 97 | |
| 98 | //---------------------------------------------------------------------------- |
| 99 | /** |
| 100 | A proxy for representing table values. |
| 101 | */ |
| 102 | class Proxy |
| 103 | { |
| 104 | private: |
| 105 | lua_State* m_L; |
| 106 | int m_tableRef; |
| 107 | int m_keyRef; |
| 108 | |
| 109 | public: |
| 110 | //-------------------------------------------------------------------------- |
| 111 | /** |
| 112 | Construct a Proxy from a table value. |
| 113 | |
| 114 | The table is in the registry, and the key is at the top of the stack. |
| 115 | The key is popped off the stack. |
| 116 | */ |
| 117 | Proxy (lua_State* L, int tableRef) |
| 118 | : m_L (L) |
| 119 | , m_tableRef (tableRef) |
| 120 | , m_keyRef (luaL_ref (L, LUA_REGISTRYINDEX)) |
| 121 | { |
| 122 | } |
| 123 | |
| 124 | //-------------------------------------------------------------------------- |
| 125 | /** |
| 126 | Create a Proxy via copy constructor. |
| 127 | |
| 128 | It is best to avoid code paths that invoke this, because it creates |
| 129 | an extra temporary Lua reference. Typically this is done by passing |
| 130 | the Proxy parameter as a `const` reference. |
| 131 | */ |
| 132 | Proxy (Proxy const& other) |
| 133 | : m_L (other.m_L) |
| 134 | , m_tableRef (other.m_tableRef) |
| 135 | { |
| 136 | // If this assert goes off it means code is taking this path, |
| 137 | // which is better avoided. |
| 138 | // |
| 139 | assert (0); |
| 140 | |
| 141 | lua_rawgeti (m_L, LUA_REGISTRYINDEX, other.m_keyRef); |
| 142 | m_keyRef = luaL_ref (m_L, LUA_REGISTRYINDEX); |
| 143 | } |
| 144 | |
| 145 | //-------------------------------------------------------------------------- |
| 146 | /** |
| 147 | Destroy the proxy. |
| 148 | |
| 149 | This does not destroy the table value. |
| 150 | */ |
| 151 | ~Proxy () |
| 152 | { |
| 153 | luaL_unref (m_L, LUA_REGISTRYINDEX, m_keyRef); |
| 154 | } |
| 155 | |
| 156 | //-------------------------------------------------------------------------- |
| 157 | /** |
| 158 | Return a reference to the table value. |
| 159 | */ |
| 160 | int createRef () const |
| 161 | { |
| 162 | push (m_L); |
| 163 | return luaL_ref (m_L, LUA_REGISTRYINDEX); |
| 164 | } |
| 165 | |
| 166 | //-------------------------------------------------------------------------- |
| 167 | /** |
| 168 | Assign a new value to this table key. |
| 169 | |
| 170 | This may invoke metamethods. |
| 171 | */ |
| 172 | template <class T> |
| 173 | Proxy& operator= (T v) |
| 174 | { |
| 175 | StackPop p (m_L, 1); |
| 176 | lua_rawgeti (m_L, LUA_REGISTRYINDEX, m_tableRef); |
| 177 | lua_rawgeti (m_L, LUA_REGISTRYINDEX, m_keyRef); |
| 178 | Stack <T>::push (m_L, v); |
| 179 | lua_rawset (m_L, -3); |
| 180 | return *this; |
| 181 | } |
| 182 | |
| 183 | //-------------------------------------------------------------------------- |
| 184 | /** |
| 185 | Assign a new value to this table key. |
| 186 | |
| 187 | The assignment is raw, no metamethods are invoked. |
| 188 | */ |
| 189 | template <class T> |
| 190 | Proxy& rawset (T v) |
| 191 | { |
| 192 | StackPop p (m_L, 1); |
| 193 | lua_rawgeti (m_L, LUA_REGISTRYINDEX, m_tableRef); |
| 194 | lua_rawgeti (m_L, LUA_REGISTRYINDEX, m_keyRef); |
| 195 | Stack <T>::push (m_L, v); |
| 196 | lua_settable (m_L, -3); |
| 197 | return *this; |
| 198 | } |
| 199 | |
| 200 | //========================================================================== |
| 201 | // |
| 202 | // This group of member functions mirrors the member functions in LuaRef. |
| 203 | |
| 204 | /** Retrieve the lua_State associated with the table value. |
| 205 | */ |
| 206 | lua_State* state () const |
| 207 | { |
| 208 | return m_L; |
| 209 | } |
| 210 | |
| 211 | //-------------------------------------------------------------------------- |
| 212 | /** |
| 213 | Push the value onto the Lua stack. |
| 214 | */ |
| 215 | void push (lua_State* L) const |
| 216 | { |
| 217 | assert (equalstates (L, m_L)); |
| 218 | lua_rawgeti (L, LUA_REGISTRYINDEX, m_tableRef); |
| 219 | lua_rawgeti (L, LUA_REGISTRYINDEX, m_keyRef); |
| 220 | lua_gettable (L, -2); |
| 221 | lua_remove (L, -2); // remove the table |
| 222 | } |
| 223 | |
| 224 | //-------------------------------------------------------------------------- |
| 225 | /** |
| 226 | Determine the object type. |
| 227 | |
| 228 | The return values are the same as for `lua_type`. |
| 229 | */ |
| 230 | int type () const |
| 231 | { |
| 232 | int result; |
| 233 | push (m_L); |
| 234 | result = lua_type (m_L, -1); |
| 235 | lua_pop (m_L, 1); |
| 236 | return result; |
| 237 | } |
| 238 | |
| 239 | inline bool isNil () const { return type () == LUA_TNIL; } |
| 240 | inline bool isNumber () const { return type () == LUA_TNUMBER; } |
| 241 | inline bool isString () const { return type () == LUA_TSTRING; } |
| 242 | inline bool isTable () const { return type () == LUA_TTABLE; } |
| 243 | inline bool isFunction () const { return type () == LUA_TFUNCTION; } |
| 244 | inline bool isUserdata () const { return type () == LUA_TUSERDATA; } |
| 245 | inline bool isThread () const { return type () == LUA_TTHREAD; } |
| 246 | inline bool isLightUserdata () const { return type () == LUA_TLIGHTUSERDATA; } |
| 247 | |
| 248 | //-------------------------------------------------------------------------- |
| 249 | /** |
| 250 | Perform an explicit conversion. |
| 251 | */ |
| 252 | template <class T> |
| 253 | T cast () const |
| 254 | { |
| 255 | StackPop p (m_L, 1); |
| 256 | push (m_L); |
| 257 | |
| 258 | // lua_gettop is used because Userdata::getClass() doesn't handle |
| 259 | // negative stack indexes. |
| 260 | // |
| 261 | return Stack <T>::get (m_L, lua_gettop (m_L)); |
| 262 | } |
| 263 | |
| 264 | //-------------------------------------------------------------------------- |
| 265 | /** |
| 266 | Universal implicit conversion operator. |
| 267 | |
| 268 | NOTE: Visual Studio 2010 and 2012 have a bug where this function |
| 269 | is not used. See: |
| 270 | |
| 271 | http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/e30b2664-a92d-445c-9db2-e8e0fbde2014 |
| 272 | https://connect.microsoft.com/VisualStudio/feedback/details/771509/correct-code-doesnt-compile |
| 273 | |
| 274 | // This code snippet fails to compile in vs2010,vs2012 |
| 275 | struct S { |
| 276 | template <class T> inline operator T () const { return T (); } |
| 277 | }; |
| 278 | int main () { |
| 279 | S () || false; |
| 280 | return 0; |
| 281 | } |
| 282 | */ |
| 283 | template <class T> |
| 284 | inline operator T () const |
| 285 | { |
| 286 | return cast <T> (); |
| 287 | } |
| 288 | |
| 289 | //-------------------------------------------------------------------------- |
| 290 | /** |
| 291 | Universal comparison operators. |
| 292 | */ |
| 293 | /** @{ */ |
| 294 | template <class T> |
| 295 | bool operator== (T rhs) const |
| 296 | { |
| 297 | StackPop p (m_L, 2); |
| 298 | push (m_L); |
| 299 | Stack <T>::push (m_L, rhs); |
| 300 | return lua_compare (m_L, -2, -1, LUA_OPEQ) == 1; |
| 301 | } |
| 302 | |
| 303 | template <class T> |
| 304 | bool operator< (T rhs) const |
| 305 | { |
| 306 | StackPop p (m_L, 2); |
| 307 | push (m_L); |
| 308 | Stack <T>::push (m_L, rhs); |
| 309 | return lua_compare (m_L, -2, -1, LUA_OPLT) == 1; |
| 310 | } |
| 311 | |
| 312 | template <class T> |
| 313 | bool operator<= (T rhs) const |
| 314 | { |
| 315 | StackPop p (m_L, 2); |
| 316 | push (m_L); |
| 317 | Stack <T>::push (m_L, rhs); |
| 318 | return lua_compare (m_L, -2, -1, LUA_OPLE) == 1; |
| 319 | } |
| 320 | |
| 321 | template <class T> |
| 322 | bool operator> (T rhs) const |
| 323 | { |
| 324 | StackPop p (m_L, 2); |
| 325 | push (m_L); |
| 326 | Stack <T>::push (m_L, rhs); |
| 327 | return lua_compare (m_L, -1, -2, LUA_OPLT) == 1; |
| 328 | } |
| 329 | |
| 330 | template <class T> |
| 331 | bool operator>= (T rhs) const |
| 332 | { |
| 333 | StackPop p (m_L, 2); |
| 334 | push (m_L); |
| 335 | Stack <T>::push (m_L, rhs); |
| 336 | return lua_compare (m_L, -1, -2, LUA_OPLE) == 1; |
| 337 | } |
| 338 | |
| 339 | template <class T> |
| 340 | bool rawequal (T rhs) const |
| 341 | { |
| 342 | StackPop p (m_L, 2); |
| 343 | push (m_L); |
| 344 | Stack <T>::push (m_L, rhs); |
| 345 | return lua_rawequal (m_L, -1, -2) == 1; |
| 346 | } |
| 347 | /** @} */ |
| 348 | |
| 349 | //-------------------------------------------------------------------------- |
| 350 | /** |
| 351 | Access a table value using a key. |
| 352 | |
| 353 | This invokes metamethods. |
| 354 | */ |
| 355 | template <class T> |
| 356 | Proxy operator[] (T key) const |
| 357 | { |
| 358 | return LuaRef (*this) [key]; |
| 359 | } |
| 360 | |
| 361 | //-------------------------------------------------------------------------- |
| 362 | /** |
| 363 | Access a table value using a key. |
| 364 | |
| 365 | The operation is raw, metamethods are not invoked. The result is |
| 366 | passed by value and may not be modified. |
| 367 | */ |
| 368 | template <class T> |
| 369 | LuaRef rawget (T key) const |
| 370 | { |
| 371 | StackPop (m_L, 1); |
| 372 | push (m_L); |
| 373 | Stack <T>::push (m_L, key); |
| 374 | lua_rawget (m_L, -2); |
| 375 | return LuaRef (m_L, FromStack ()); |
| 376 | } |
| 377 | |
| 378 | //-------------------------------------------------------------------------- |
| 379 | /** |
| 380 | Append a value to the table. |
| 381 | |
| 382 | If the table is a sequence this will add another element to it. |
| 383 | */ |
| 384 | template <class T> |
| 385 | void append (T v) const |
| 386 | { |
| 387 | push (m_L); |
| 388 | Stack <T>::push (m_L, v); |
| 389 | luaL_ref (m_L, -2); |
| 390 | lua_pop (m_L, 1); |
| 391 | } |
| 392 | |
| 393 | //-------------------------------------------------------------------------- |
| 394 | /** |
| 395 | Call the length operator. |
| 396 | |
| 397 | This is identical to applying the Lua # operator. |
| 398 | */ |
| 399 | int length () const |
| 400 | { |
| 401 | StackPop p (m_L, 1); |
| 402 | push (m_L); |
| 403 | return get_length (m_L, -1); |
| 404 | } |
| 405 | |
| 406 | //-------------------------------------------------------------------------- |
| 407 | /** |
| 408 | Call Lua code. |
| 409 | |
| 410 | These overloads allow Lua code to be called with up to 8 parameters. |
| 411 | The return value is provided as a LuaRef (which may be LUA_REFNIL). |
| 412 | If an error occurs, a LuaException is thrown. |
| 413 | */ |
| 414 | /** @{ */ |
| 415 | LuaRef const operator() () const |
| 416 | { |
| 417 | push (m_L); |
| 418 | LuaException::pcall (m_L, 0, 1); |
| 419 | return LuaRef (m_L, FromStack ()); |
| 420 | } |
| 421 | |
| 422 | template <class P1> |
| 423 | LuaRef const operator() (P1 p1) const |
| 424 | { |
| 425 | push (m_L); |
| 426 | Stack <P1>::push (m_L, p1); |
| 427 | LuaException::pcall (m_L, 1, 1); |
| 428 | return LuaRef (m_L, FromStack ()); |
| 429 | } |
| 430 | |
| 431 | template <class P1, class P2> |
| 432 | LuaRef const operator() (P1 p1, P2 p2) const |
| 433 | { |
| 434 | push (m_L); |
| 435 | Stack <P1>::push (m_L, p1); |
| 436 | Stack <P2>::push (m_L, p2); |
| 437 | LuaException::pcall (m_L, 2, 1); |
| 438 | return LuaRef (m_L, FromStack ()); |
| 439 | } |
| 440 | |
| 441 | template <class P1, class P2, class P3> |
| 442 | LuaRef const operator() (P1 p1, P2 p2, P3 p3) const |
| 443 | { |
| 444 | push (m_L); |
| 445 | Stack <P1>::push (m_L, p1); |
| 446 | Stack <P2>::push (m_L, p2); |
| 447 | Stack <P3>::push (m_L, p3); |
| 448 | LuaException::pcall (m_L, 3, 1); |
| 449 | return LuaRef (m_L, FromStack ()); |
| 450 | } |
| 451 | |
| 452 | template <class P1, class P2, class P3, class P4> |
| 453 | LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4) const |
| 454 | { |
| 455 | push (m_L); |
| 456 | Stack <P1>::push (m_L, p1); |
| 457 | Stack <P2>::push (m_L, p2); |
| 458 | Stack <P3>::push (m_L, p3); |
| 459 | Stack <P4>::push (m_L, p4); |
| 460 | LuaException::pcall (m_L, 4, 1); |
| 461 | return LuaRef (m_L, FromStack ()); |
| 462 | } |
| 463 | |
| 464 | template <class P1, class P2, class P3, class P4, class P5> |
| 465 | LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) const |
| 466 | { |
| 467 | push (m_L); |
| 468 | Stack <P1>::push (m_L, p1); |
| 469 | Stack <P2>::push (m_L, p2); |
| 470 | Stack <P3>::push (m_L, p3); |
| 471 | Stack <P4>::push (m_L, p4); |
| 472 | Stack <P5>::push (m_L, p5); |
| 473 | LuaException::pcall (m_L, 5, 1); |
| 474 | return LuaRef (m_L, FromStack ()); |
| 475 | } |
| 476 | |
| 477 | template <class P1, class P2, class P3, class P4, class P5, class P6> |
| 478 | LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) const |
| 479 | { |
| 480 | push (m_L); |
| 481 | Stack <P1>::push (m_L, p1); |
| 482 | Stack <P2>::push (m_L, p2); |
| 483 | Stack <P3>::push (m_L, p3); |
| 484 | Stack <P4>::push (m_L, p4); |
| 485 | Stack <P5>::push (m_L, p5); |
| 486 | Stack <P6>::push (m_L, p6); |
| 487 | LuaException::pcall (m_L, 6, 1); |
| 488 | return LuaRef (m_L, FromStack ()); |
| 489 | } |
| 490 | |
| 491 | template <class P1, class P2, class P3, class P4, class P5, class P6, class P7> |
| 492 | LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) const |
| 493 | { |
| 494 | push (m_L); |
| 495 | Stack <P1>::push (m_L, p1); |
| 496 | Stack <P2>::push (m_L, p2); |
| 497 | Stack <P3>::push (m_L, p3); |
| 498 | Stack <P4>::push (m_L, p4); |
| 499 | Stack <P5>::push (m_L, p5); |
| 500 | Stack <P6>::push (m_L, p6); |
| 501 | Stack <P7>::push (m_L, p7); |
| 502 | LuaException::pcall (m_L, 7, 1); |
| 503 | return LuaRef (m_L, FromStack ()); |
| 504 | } |
| 505 | |
| 506 | template <class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8> |
| 507 | LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) const |
| 508 | { |
| 509 | push (m_L); |
| 510 | Stack <P1>::push (m_L, p1); |
| 511 | Stack <P2>::push (m_L, p2); |
| 512 | Stack <P3>::push (m_L, p3); |
| 513 | Stack <P4>::push (m_L, p4); |
| 514 | Stack <P5>::push (m_L, p5); |
| 515 | Stack <P6>::push (m_L, p6); |
| 516 | Stack <P7>::push (m_L, p7); |
| 517 | Stack <P8>::push (m_L, p8); |
| 518 | LuaException::pcall (m_L, 8, 1); |
| 519 | return LuaRef (m_L, FromStack ()); |
| 520 | } |
| 521 | /** @} */ |
| 522 | |
| 523 | //========================================================================== |
| 524 | }; |
| 525 | |
| 526 | private: |
| 527 | friend struct Stack <LuaRef>; |
| 528 | |
| 529 | //---------------------------------------------------------------------------- |
| 530 | /** |
| 531 | Type tag for stack construction. |
| 532 | */ |
| 533 | struct FromStack { }; |
| 534 | |
| 535 | //---------------------------------------------------------------------------- |
| 536 | /** |
| 537 | Create a reference to an object at the top of the Lua stack and pop it. |
| 538 | |
| 539 | This constructor is private and not invoked directly. |
| 540 | Instead, use the `fromStack` function. |
| 541 | |
| 542 | @note The object is popped. |
| 543 | */ |
| 544 | LuaRef (lua_State* L, FromStack) |
| 545 | : m_L (L) |
| 546 | { |
| 547 | m_ref = luaL_ref (m_L, LUA_REGISTRYINDEX); |
| 548 | } |
| 549 | |
| 550 | //---------------------------------------------------------------------------- |
| 551 | /** |
| 552 | Create a reference to an object on the Lua stack. |
| 553 | |
| 554 | This constructor is private and not invoked directly. |
| 555 | Instead, use the `fromStack` function. |
| 556 | |
| 557 | @note The object is not popped. |
| 558 | */ |
| 559 | LuaRef (lua_State* L, int index, FromStack) |
| 560 | : m_L (L) |
| 561 | { |
| 562 | lua_pushvalue (m_L, index); |
| 563 | m_ref = luaL_ref (m_L, LUA_REGISTRYINDEX); |
| 564 | } |
| 565 | |
| 566 | //---------------------------------------------------------------------------- |
| 567 | |
| 568 | // This type of construction is disallowed, since we don't have a `lua_State`. |
| 569 | // |
| 570 | template <class T> |
| 571 | LuaRef (T) |
| 572 | { |
| 573 | } |
| 574 | |
| 575 | //---------------------------------------------------------------------------- |
| 576 | /** |
| 577 | Create a reference to this ref. |
| 578 | |
| 579 | This is used internally. |
| 580 | */ |
| 581 | int createRef () const |
| 582 | { |
| 583 | if (m_ref != LUA_REFNIL) |
| 584 | { |
| 585 | push (m_L); |
| 586 | return luaL_ref (m_L, LUA_REGISTRYINDEX); |
| 587 | } |
| 588 | else |
| 589 | { |
| 590 | return LUA_REFNIL; |
| 591 | } |
| 592 | } |
| 593 | |
| 594 | public: |
| 595 | //---------------------------------------------------------------------------- |
| 596 | /** |
| 597 | Create a nil reference. |
| 598 | |
| 599 | The LuaRef may be assigned later. |
| 600 | */ |
| 601 | LuaRef (lua_State* L) |
| 602 | : m_L (L) |
| 603 | , m_ref (LUA_REFNIL) |
| 604 | { |
| 605 | } |
| 606 | |
| 607 | //---------------------------------------------------------------------------- |
| 608 | /** |
| 609 | Create a reference to a value. |
| 610 | */ |
| 611 | template <class T> |
| 612 | LuaRef (lua_State* L, T v) |
| 613 | : m_L (L) |
| 614 | { |
| 615 | Stack <T>::push (m_L, v); |
| 616 | m_ref = luaL_ref (m_L, LUA_REGISTRYINDEX); |
| 617 | } |
| 618 | |
| 619 | //---------------------------------------------------------------------------- |
| 620 | /** |
| 621 | Create a reference to a table value. |
| 622 | */ |
| 623 | LuaRef (Proxy const& v) |
| 624 | : m_L (v.state ()) |
| 625 | , m_ref (v.createRef ()) |
| 626 | { |
| 627 | } |
| 628 | |
| 629 | //---------------------------------------------------------------------------- |
| 630 | /** |
| 631 | Create a new reference to an existing reference. |
| 632 | */ |
| 633 | LuaRef (LuaRef const& other) |
| 634 | : m_L (other.m_L) |
| 635 | , m_ref (other.createRef ()) |
| 636 | { |
| 637 | } |
| 638 | |
| 639 | //---------------------------------------------------------------------------- |
| 640 | /** |
| 641 | Destroy a reference. |
| 642 | |
| 643 | The corresponding Lua registry reference will be released. |
| 644 | |
| 645 | @note If the state refers to a thread, it is the responsibility of the |
| 646 | caller to ensure that the thread still exists when the LuaRef |
| 647 | is destroyed. |
| 648 | */ |
| 649 | ~LuaRef () |
| 650 | { |
| 651 | luaL_unref (m_L, LUA_REGISTRYINDEX, m_ref); |
| 652 | } |
| 653 | |
| 654 | //---------------------------------------------------------------------------- |
| 655 | /** |
| 656 | Return a LuaRef from a stack item. |
| 657 | |
| 658 | The stack item is not popped. |
| 659 | */ |
| 660 | static LuaRef fromStack (lua_State* L, int index) |
| 661 | { |
| 662 | lua_pushvalue (L, index); |
| 663 | return LuaRef (L, FromStack ()); |
| 664 | } |
| 665 | |
| 666 | //---------------------------------------------------------------------------- |
| 667 | /** |
| 668 | Create a new empty table and return a reference to it. |
| 669 | |
| 670 | It is also possible to use the free function `newTable`. |
| 671 | |
| 672 | @see ::getGlobal |
| 673 | */ |
| 674 | static LuaRef newTable (lua_State* L) |
| 675 | { |
| 676 | lua_newtable (L); |
| 677 | return LuaRef (L, FromStack ()); |
| 678 | } |
| 679 | |
| 680 | //---------------------------------------------------------------------------- |
| 681 | /** |
| 682 | Return a reference to a named global. |
| 683 | |
| 684 | It is also possible to use the free function `getGlobal`. |
| 685 | |
| 686 | @see ::getGlobal |
| 687 | */ |
| 688 | static LuaRef getGlobal (lua_State *L, char const* name) |
| 689 | { |
| 690 | lua_getglobal (L, name); |
| 691 | return LuaRef (L, FromStack ()); |
| 692 | } |
| 693 | |
| 694 | //---------------------------------------------------------------------------- |
| 695 | /** |
| 696 | Assign a different value to this LuaRef. |
| 697 | */ |
| 698 | template <class T> |
| 699 | LuaRef& operator= (T rhs) |
| 700 | { |
| 701 | luaL_unref (m_L, LUA_REGISTRYINDEX, m_ref); |
| 702 | Stack <T>::push (m_L, rhs); |
| 703 | m_ref = luaL_ref (m_L, LUA_REGISTRYINDEX); |
| 704 | return *this; |
| 705 | } |
| 706 | |
| 707 | //---------------------------------------------------------------------------- |
| 708 | /** |
| 709 | Assign another LuaRef to this LuaRef. |
| 710 | */ |
| 711 | LuaRef& operator= (LuaRef const& rhs) |
| 712 | { |
| 713 | luaL_unref (m_L, LUA_REGISTRYINDEX, m_ref); |
| 714 | rhs.push (m_L); |
| 715 | m_L = rhs.state (); |
| 716 | m_ref = luaL_ref (m_L, LUA_REGISTRYINDEX); |
| 717 | return *this; |
| 718 | } |
| 719 | |
| 720 | //---------------------------------------------------------------------------- |
| 721 | /** |
| 722 | converts to a string using luas tostring function |
| 723 | */ |
| 724 | std::string tostring() const |
| 725 | { |
| 726 | lua_getglobal (m_L, "tostring"); |
| 727 | push (m_L); |
| 728 | lua_call (m_L, 1, 1); |
| 729 | const char* str = lua_tostring(m_L, 1); |
| 730 | lua_pop(m_L, 1); |
| 731 | return std::string(str); |
| 732 | } |
| 733 | |
| 734 | //---------------------------------------------------------------------------- |
| 735 | /** |
| 736 | Print a text description of the value to a stream. |
| 737 | |
| 738 | This is used for diagnostics. |
| 739 | */ |
| 740 | void print (std::ostream& os) const |
| 741 | { |
| 742 | switch (type ()) |
| 743 | { |
| 744 | case LUA_TNIL: |
| 745 | os << "nil"; |
| 746 | break; |
| 747 | |
| 748 | case LUA_TNUMBER: |
| 749 | os << cast <lua_Number> (); |
| 750 | break; |
| 751 | |
| 752 | case LUA_TBOOLEAN: |
| 753 | os << (cast <bool> () ? "true" : "false"); |
| 754 | break; |
| 755 | |
| 756 | case LUA_TSTRING: |
| 757 | os << '"' << cast <std::string> () << '"'; |
| 758 | break; |
| 759 | |
| 760 | case LUA_TTABLE: |
| 761 | os << "table: " << tostring(); |
| 762 | break; |
| 763 | |
| 764 | case LUA_TFUNCTION: |
| 765 | os << "function: " << tostring(); |
| 766 | break; |
| 767 | |
| 768 | case LUA_TUSERDATA: |
| 769 | os << "userdata: " << tostring(); |
| 770 | break; |
| 771 | |
| 772 | case LUA_TTHREAD: |
| 773 | os << "thread: " << tostring(); |
| 774 | break; |
| 775 | |
| 776 | case LUA_TLIGHTUSERDATA: |
| 777 | os << "lightuserdata: " << tostring(); |
| 778 | break; |
| 779 | |
| 780 | default: |
| 781 | os << "unknown"; |
| 782 | break; |
| 783 | } |
| 784 | } |
| 785 | |
| 786 | //============================================================================ |
| 787 | // |
| 788 | // This group of member functions is mirrored in Proxy |
| 789 | // |
| 790 | |
| 791 | /** Retrieve the lua_State associated with the reference. |
| 792 | */ |
| 793 | lua_State* state () const |
| 794 | { |
| 795 | return m_L; |
| 796 | } |
| 797 | |
| 798 | //---------------------------------------------------------------------------- |
| 799 | /** |
| 800 | Place the object onto the Lua stack. |
| 801 | */ |
| 802 | void push (lua_State* L) const |
| 803 | { |
| 804 | assert (equalstates (L, m_L)); |
| 805 | lua_rawgeti (L, LUA_REGISTRYINDEX, m_ref); |
| 806 | } |
| 807 | |
| 808 | //---------------------------------------------------------------------------- |
| 809 | /** |
| 810 | Pop the top of Lua stack and assign the ref to m_ref |
| 811 | */ |
| 812 | void pop (lua_State* L) |
| 813 | { |
| 814 | assert (equalstates (L, m_L)); |
| 815 | luaL_unref (m_L, LUA_REGISTRYINDEX, m_ref); |
| 816 | m_ref = luaL_ref (m_L, LUA_REGISTRYINDEX); |
| 817 | } |
| 818 | |
| 819 | //---------------------------------------------------------------------------- |
| 820 | /** |
| 821 | Determine the object type. |
| 822 | |
| 823 | The return values are the same as for `lua_type`. |
| 824 | */ |
| 825 | /** @{ */ |
| 826 | int type () const |
| 827 | { |
| 828 | int result; |
| 829 | if (m_ref != LUA_REFNIL) |
| 830 | { |
| 831 | push (m_L); |
| 832 | result = lua_type (m_L, -1); |
| 833 | lua_pop (m_L, 1); |
| 834 | } |
| 835 | else |
| 836 | { |
| 837 | result = LUA_TNIL; |
| 838 | } |
| 839 | |
| 840 | return result; |
| 841 | } |
| 842 | |
| 843 | // should never happen |
| 844 | //inline bool isNone () const { return m_ref == LUA_NOREF; } |
| 845 | |
| 846 | inline bool isNil () const { return type () == LUA_TNIL; } |
| 847 | inline bool isNumber () const { return type () == LUA_TNUMBER; } |
| 848 | inline bool isString () const { return type () == LUA_TSTRING; } |
| 849 | inline bool isTable () const { return type () == LUA_TTABLE; } |
| 850 | inline bool isFunction () const { return type () == LUA_TFUNCTION; } |
| 851 | inline bool isUserdata () const { return type () == LUA_TUSERDATA; } |
| 852 | inline bool isThread () const { return type () == LUA_TTHREAD; } |
| 853 | inline bool isLightUserdata () const { return type () == LUA_TLIGHTUSERDATA; } |
| 854 | /** @} */ |
| 855 | |
| 856 | //---------------------------------------------------------------------------- |
| 857 | /** |
| 858 | Perform an explicit conversion. |
| 859 | */ |
| 860 | template <class T> |
| 861 | T cast () const |
| 862 | { |
| 863 | StackPop p (m_L, 1); |
| 864 | push (m_L); |
| 865 | |
| 866 | // lua_gettop is used because Userdata::getClass() doesn't handle |
| 867 | // negative stack indexes. |
| 868 | // |
| 869 | return Stack <T>::get (m_L, lua_gettop (m_L)); |
| 870 | } |
| 871 | |
| 872 | //---------------------------------------------------------------------------- |
| 873 | /** |
| 874 | Universal implicit conversion operator. |
| 875 | |
| 876 | NOTE: Visual Studio 2010 and 2012 have a bug where this function |
| 877 | is not used. See: |
| 878 | |
| 879 | http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/e30b2664-a92d-445c-9db2-e8e0fbde2014 |
| 880 | https://connect.microsoft.com/VisualStudio/feedback/details/771509/correct-code-doesnt-compile |
| 881 | |
| 882 | // This code snippet fails to compile in vs2010,vs2012 |
| 883 | struct S { |
| 884 | template <class T> inline operator T () const { return T (); } |
| 885 | }; |
| 886 | int main () { |
| 887 | S () || false; |
| 888 | return 0; |
| 889 | } |
| 890 | */ |
| 891 | template <class T> |
| 892 | inline operator T () const |
| 893 | { |
| 894 | return cast <T> (); |
| 895 | } |
| 896 | |
| 897 | //---------------------------------------------------------------------------- |
| 898 | /** |
| 899 | Universal comparison operators. |
| 900 | */ |
| 901 | /** @{ */ |
| 902 | template <class T> |
| 903 | bool operator== (T rhs) const |
| 904 | { |
| 905 | StackPop p (m_L, 2); |
| 906 | push (m_L); |
| 907 | Stack <T>::push (m_L, rhs); |
| 908 | return lua_compare (m_L, -2, -1, LUA_OPEQ) == 1; |
| 909 | } |
| 910 | |
| 911 | template <class T> |
| 912 | bool operator< (T rhs) const |
| 913 | { |
| 914 | StackPop p (m_L, 2); |
| 915 | push (m_L); |
| 916 | Stack <T>::push (m_L, rhs); |
| 917 | return lua_compare (m_L, -2, -1, LUA_OPLT) == 1; |
| 918 | } |
| 919 | |
| 920 | template <class T> |
| 921 | bool operator<= (T rhs) const |
| 922 | { |
| 923 | StackPop p (m_L, 2); |
| 924 | push (m_L); |
| 925 | Stack <T>::push (m_L, rhs); |
| 926 | return lua_compare (m_L, -2, -1, LUA_OPLE) == 1; |
| 927 | } |
| 928 | |
| 929 | template <class T> |
| 930 | bool operator> (T rhs) const |
| 931 | { |
| 932 | StackPop p (m_L, 2); |
| 933 | push (m_L); |
| 934 | Stack <T>::push (m_L, rhs); |
| 935 | return lua_compare (m_L, -1, -2, LUA_OPLT) == 1; |
| 936 | } |
| 937 | |
| 938 | template <class T> |
| 939 | bool operator>= (T rhs) const |
| 940 | { |
| 941 | StackPop p (m_L, 2); |
| 942 | push (m_L); |
| 943 | Stack <T>::push (m_L, rhs); |
| 944 | return lua_compare (m_L, -1, -2, LUA_OPLE) == 1; |
| 945 | } |
| 946 | |
| 947 | template <class T> |
| 948 | bool rawequal (T rhs) const |
| 949 | { |
| 950 | StackPop p (m_L, 2); |
| 951 | push (m_L); |
| 952 | Stack <T>::push (m_L, rhs); |
| 953 | return lua_rawequal (m_L, -1, -2) == 1; |
| 954 | } |
| 955 | /** @} */ |
| 956 | |
| 957 | //---------------------------------------------------------------------------- |
| 958 | /** |
| 959 | Append a value to the table. |
| 960 | |
| 961 | If the table is a sequence this will add another element to it. |
| 962 | */ |
| 963 | template <class T> |
| 964 | void append (T v) const |
| 965 | { |
| 966 | push (m_L); |
| 967 | Stack <T>::push (m_L, v); |
| 968 | luaL_ref (m_L, -2); |
| 969 | lua_pop (m_L, 1); |
| 970 | } |
| 971 | |
| 972 | //---------------------------------------------------------------------------- |
| 973 | /** |
| 974 | Call the length operator. |
| 975 | |
| 976 | This is identical to applying the Lua # operator. |
| 977 | */ |
| 978 | int length () const |
| 979 | { |
| 980 | StackPop p (m_L, 1); |
| 981 | push (m_L); |
| 982 | return get_length (m_L, -1); |
| 983 | } |
| 984 | |
| 985 | //---------------------------------------------------------------------------- |
| 986 | /** |
| 987 | Access a table value using a key. |
| 988 | |
| 989 | This invokes metamethods. |
| 990 | */ |
| 991 | template <class T> |
| 992 | Proxy operator[] (T key) const |
| 993 | { |
| 994 | Stack <T>::push (m_L, key); |
| 995 | return Proxy (m_L, m_ref); |
| 996 | } |
| 997 | |
| 998 | //---------------------------------------------------------------------------- |
| 999 | /** |
| 1000 | Call Lua code. |
| 1001 | |
| 1002 | These overloads allow Lua code to be called with up to 8 parameters. |
| 1003 | The return value is provided as a LuaRef (which may be LUA_REFNIL). |
| 1004 | If an error occurs, a LuaException is thrown. |
| 1005 | */ |
| 1006 | /** @{ */ |
| 1007 | LuaRef const operator() () const |
| 1008 | { |
| 1009 | push (m_L); |
| 1010 | LuaException::pcall (m_L, 0, 1); |
| 1011 | return LuaRef (m_L, FromStack ()); |
| 1012 | } |
| 1013 | |
| 1014 | template <class P1> |
| 1015 | LuaRef const operator() (P1 p1) const |
| 1016 | { |
| 1017 | push (m_L); |
| 1018 | Stack <P1>::push (m_L, p1); |
| 1019 | LuaException::pcall (m_L, 1, 1); |
| 1020 | return LuaRef (m_L, FromStack ()); |
| 1021 | } |
| 1022 | |
| 1023 | template <class P1, class P2> |
| 1024 | LuaRef const operator() (P1 p1, P2 p2) const |
| 1025 | { |
| 1026 | push (m_L); |
| 1027 | Stack <P1>::push (m_L, p1); |
| 1028 | Stack <P2>::push (m_L, p2); |
| 1029 | LuaException::pcall (m_L, 2, 1); |
| 1030 | return LuaRef (m_L, FromStack ()); |
| 1031 | } |
| 1032 | |
| 1033 | template <class P1, class P2, class P3> |
| 1034 | LuaRef const operator() (P1 p1, P2 p2, P3 p3) const |
| 1035 | { |
| 1036 | push (m_L); |
| 1037 | Stack <P1>::push (m_L, p1); |
| 1038 | Stack <P2>::push (m_L, p2); |
| 1039 | Stack <P3>::push (m_L, p3); |
| 1040 | LuaException::pcall (m_L, 3, 1); |
| 1041 | return LuaRef (m_L, FromStack ()); |
| 1042 | } |
| 1043 | |
| 1044 | template <class P1, class P2, class P3, class P4> |
| 1045 | LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4) const |
| 1046 | { |
| 1047 | push (m_L); |
| 1048 | Stack <P1>::push (m_L, p1); |
| 1049 | Stack <P2>::push (m_L, p2); |
| 1050 | Stack <P3>::push (m_L, p3); |
| 1051 | Stack <P4>::push (m_L, p4); |
| 1052 | LuaException::pcall (m_L, 4, 1); |
| 1053 | return LuaRef (m_L, FromStack ()); |
| 1054 | } |
| 1055 | |
| 1056 | template <class P1, class P2, class P3, class P4, class P5> |
| 1057 | LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) const |
| 1058 | { |
| 1059 | push (m_L); |
| 1060 | Stack <P1>::push (m_L, p1); |
| 1061 | Stack <P2>::push (m_L, p2); |
| 1062 | Stack <P3>::push (m_L, p3); |
| 1063 | Stack <P4>::push (m_L, p4); |
| 1064 | Stack <P5>::push (m_L, p5); |
| 1065 | LuaException::pcall (m_L, 5, 1); |
| 1066 | return LuaRef (m_L, FromStack ()); |
| 1067 | } |
| 1068 | |
| 1069 | template <class P1, class P2, class P3, class P4, class P5, class P6> |
| 1070 | LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) const |
| 1071 | { |
| 1072 | push (m_L); |
| 1073 | Stack <P1>::push (m_L, p1); |
| 1074 | Stack <P2>::push (m_L, p2); |
| 1075 | Stack <P3>::push (m_L, p3); |
| 1076 | Stack <P4>::push (m_L, p4); |
| 1077 | Stack <P5>::push (m_L, p5); |
| 1078 | Stack <P6>::push (m_L, p6); |
| 1079 | LuaException::pcall (m_L, 6, 1); |
| 1080 | return LuaRef (m_L, FromStack ()); |
| 1081 | } |
| 1082 | |
| 1083 | template <class P1, class P2, class P3, class P4, class P5, class P6, class P7> |
| 1084 | LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) const |
| 1085 | { |
| 1086 | push (m_L); |
| 1087 | Stack <P1>::push (m_L, p1); |
| 1088 | Stack <P2>::push (m_L, p2); |
| 1089 | Stack <P3>::push (m_L, p3); |
| 1090 | Stack <P4>::push (m_L, p4); |
| 1091 | Stack <P5>::push (m_L, p5); |
| 1092 | Stack <P6>::push (m_L, p6); |
| 1093 | Stack <P7>::push (m_L, p7); |
| 1094 | LuaException::pcall (m_L, 7, 1); |
| 1095 | return LuaRef (m_L, FromStack ()); |
| 1096 | } |
| 1097 | |
| 1098 | template <class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8> |
| 1099 | LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) const |
| 1100 | { |
| 1101 | push (m_L); |
| 1102 | Stack <P1>::push (m_L, p1); |
| 1103 | Stack <P2>::push (m_L, p2); |
| 1104 | Stack <P3>::push (m_L, p3); |
| 1105 | Stack <P4>::push (m_L, p4); |
| 1106 | Stack <P5>::push (m_L, p5); |
| 1107 | Stack <P6>::push (m_L, p6); |
| 1108 | Stack <P7>::push (m_L, p7); |
| 1109 | Stack <P8>::push (m_L, p8); |
| 1110 | LuaException::pcall (m_L, 8, 1); |
| 1111 | return LuaRef (m_L, FromStack ()); |
| 1112 | } |
| 1113 | /** @} */ |
| 1114 | |
| 1115 | //============================================================================ |
| 1116 | |
| 1117 | private: |
| 1118 | lua_State* m_L; |
| 1119 | int m_ref; |
| 1120 | }; |
| 1121 | |
| 1122 | //------------------------------------------------------------------------------ |
| 1123 | /** |
| 1124 | Stack specialization for Nil |
| 1125 | */ |
| 1126 | template <> |
| 1127 | struct Stack <Nil> |
| 1128 | { |
| 1129 | public: |
| 1130 | static inline void push (lua_State* L, Nil) |
| 1131 | { |
| 1132 | lua_pushnil (L); |
| 1133 | } |
| 1134 | }; |
| 1135 | |
| 1136 | //------------------------------------------------------------------------------ |
| 1137 | /** |
| 1138 | Stack specialization for LuaRef. |
| 1139 | */ |
| 1140 | template <> |
| 1141 | struct Stack <LuaRef> |
| 1142 | { |
| 1143 | public: |
| 1144 | // The value is const& to prevent a copy construction. |
| 1145 | // |
| 1146 | static inline void push (lua_State* L, LuaRef const& v) |
| 1147 | { |
| 1148 | v.push (L); |
| 1149 | } |
| 1150 | |
| 1151 | static inline LuaRef get (lua_State* L, int index) |
| 1152 | { |
| 1153 | return LuaRef (L, index, LuaRef::FromStack ()); |
| 1154 | } |
| 1155 | }; |
| 1156 | |
| 1157 | //------------------------------------------------------------------------------ |
| 1158 | /** |
| 1159 | Stack specialization for Proxy. |
| 1160 | */ |
| 1161 | template <> |
| 1162 | struct Stack <LuaRef::Proxy> |
| 1163 | { |
| 1164 | public: |
| 1165 | // The value is const& to prevent a copy construction. |
| 1166 | // |
| 1167 | static inline void push (lua_State* L, LuaRef::Proxy const& v) |
| 1168 | { |
| 1169 | v.push (L); |
| 1170 | } |
| 1171 | }; |
| 1172 | |
| 1173 | //------------------------------------------------------------------------------ |
| 1174 | /** |
| 1175 | Create a reference to a new, empty table. |
| 1176 | |
| 1177 | This is a syntactic abbreviation for LuaRef::newTable(). |
| 1178 | */ |
| 1179 | inline LuaRef newTable (lua_State* L) |
| 1180 | { |
| 1181 | return LuaRef::newTable (L); |
| 1182 | } |
| 1183 | |
| 1184 | //------------------------------------------------------------------------------ |
| 1185 | /** |
| 1186 | Create a reference to a value in the global table. |
| 1187 | |
| 1188 | This is a syntactic abbreviation for LuaRef::getGlobal(). |
| 1189 | */ |
| 1190 | inline LuaRef getGlobal (lua_State *L, char const* name) |
| 1191 | { |
| 1192 | return LuaRef::getGlobal (L, name); |
| 1193 | } |
| 1194 | |
| 1195 | //------------------------------------------------------------------------------ |
| 1196 | /** |
| 1197 | Write a LuaRef to a stream. |
| 1198 | |
| 1199 | This allows LuaRef and table proxies to work with streams. |
| 1200 | */ |
| 1201 | inline std::ostream& operator<< (std::ostream& os, LuaRef const& ref) |
| 1202 | { |
| 1203 | ref.print (os); |
| 1204 | return os; |
| 1205 | } |
| 1206 | |
| 1207 | //------------------------------------------------------------------------------ |
| 1208 | |
| 1209 | // more C++-like cast syntax |
| 1210 | // |
| 1211 | template<class T> |
| 1212 | inline T LuaRef_cast(LuaRef const& lr) |
| 1213 | { |
| 1214 | return lr.cast<T>(); |
| 1215 | } |
trunk/3rdparty/luabridge/Source/LuaBridge/detail/Namespace.h
| r0 | r242832 | |
| 1 | //------------------------------------------------------------------------------ |
| 2 | /* |
| 3 | https://github.com/vinniefalco/LuaBridge |
| 4 | |
| 5 | Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com> |
| 6 | Copyright 2007, Nathan Reed |
| 7 | |
| 8 | License: The MIT License (http://www.opensource.org/licenses/mit-license.php) |
| 9 | |
| 10 | Permission is hereby granted, free of charge, to any person obtaining a copy |
| 11 | of this software and associated documentation files (the "Software"), to deal |
| 12 | in the Software without restriction, including without limitation the rights |
| 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| 14 | copies of the Software, and to permit persons to whom the Software is |
| 15 | furnished to do so, subject to the following conditions: |
| 16 | |
| 17 | The above copyright notice and this permission notice shall be included in all |
| 18 | copies or substantial portions of the Software. |
| 19 | |
| 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| 26 | SOFTWARE. |
| 27 | */ |
| 28 | //============================================================================== |
| 29 | |
| 30 | /** Provides C++ to Lua registration capabilities. |
| 31 | |
| 32 | This class is not instantiated directly, call `getGlobalNamespace` to start |
| 33 | the registration process. |
| 34 | */ |
| 35 | class Namespace |
| 36 | { |
| 37 | private: |
| 38 | Namespace& operator= (Namespace const& other); |
| 39 | |
| 40 | lua_State* const L; |
| 41 | int mutable m_stackSize; |
| 42 | |
| 43 | private: |
| 44 | //============================================================================ |
| 45 | /** |
| 46 | Error reporting. |
| 47 | |
| 48 | VF: This function looks handy, why aren't we using it? |
| 49 | */ |
| 50 | #if 0 |
| 51 | static int luaError (lua_State* L, std::string message) |
| 52 | { |
| 53 | assert (lua_isstring (L, lua_upvalueindex (1))); |
| 54 | std::string s; |
| 55 | |
| 56 | // Get information on the caller's caller to format the message, |
| 57 | // so the error appears to originate from the Lua source. |
| 58 | lua_Debug ar; |
| 59 | int result = lua_getstack (L, 2, &ar); |
| 60 | if (result != 0) |
| 61 | { |
| 62 | lua_getinfo (L, "Sl", &ar); |
| 63 | s = ar.short_src; |
| 64 | if (ar.currentline != -1) |
| 65 | { |
| 66 | // poor mans int to string to avoid <strstrream>. |
| 67 | lua_pushnumber (L, ar.currentline); |
| 68 | s = s + ":" + lua_tostring (L, -1) + ": "; |
| 69 | lua_pop (L, 1); |
| 70 | } |
| 71 | } |
| 72 | |
| 73 | s = s + message; |
| 74 | |
| 75 | return luaL_error (L, s.c_str ()); |
| 76 | } |
| 77 | #endif |
| 78 | |
| 79 | //---------------------------------------------------------------------------- |
| 80 | /** |
| 81 | Pop the Lua stack. |
| 82 | */ |
| 83 | void pop (int n) const |
| 84 | { |
| 85 | if (m_stackSize >= n && lua_gettop (L) >= n) |
| 86 | { |
| 87 | lua_pop (L, n); |
| 88 | m_stackSize -= n; |
| 89 | } |
| 90 | else |
| 91 | { |
| 92 | throw std::logic_error ("invalid stack"); |
| 93 | } |
| 94 | } |
| 95 | |
| 96 | private: |
| 97 | /** |
| 98 | Factored base to reduce template instantiations. |
| 99 | */ |
| 100 | class ClassBase |
| 101 | { |
| 102 | private: |
| 103 | ClassBase& operator= (ClassBase const& other); |
| 104 | |
| 105 | protected: |
| 106 | friend class Namespace; |
| 107 | |
| 108 | lua_State* const L; |
| 109 | int mutable m_stackSize; |
| 110 | |
| 111 | protected: |
| 112 | //-------------------------------------------------------------------------- |
| 113 | /** |
| 114 | __index metamethod for a class. |
| 115 | |
| 116 | This implements member functions, data members, and property members. |
| 117 | Functions are stored in the metatable and const metatable. Data members |
| 118 | and property members are in the __propget table. |
| 119 | |
| 120 | If the key is not found, the search proceeds up the hierarchy of base |
| 121 | classes. |
| 122 | */ |
| 123 | static int indexMetaMethod (lua_State* L) |
| 124 | { |
| 125 | int result = 0; |
| 126 | |
| 127 | assert (lua_isuserdata (L, 1)); // warn on security bypass |
| 128 | lua_getmetatable (L, 1); // get metatable for object |
| 129 | for (;;) |
| 130 | { |
| 131 | lua_pushvalue (L, 2); // push key arg2 |
| 132 | lua_rawget (L, -2); // lookup key in metatable |
| 133 | if (lua_iscfunction (L, -1)) // ensure its a cfunction |
| 134 | { |
| 135 | lua_remove (L, -2); // remove metatable |
| 136 | result = 1; |
| 137 | break; |
| 138 | } |
| 139 | else if (lua_isnil (L, -1)) |
| 140 | { |
| 141 | lua_pop (L, 1); |
| 142 | } |
| 143 | else |
| 144 | { |
| 145 | lua_pop (L, 2); |
| 146 | throw std::logic_error ("not a cfunction"); |
| 147 | } |
| 148 | |
| 149 | rawgetfield (L, -1, "__propget"); // get __propget table |
| 150 | if (lua_istable (L, -1)) // ensure it is a table |
| 151 | { |
| 152 | lua_pushvalue (L, 2); // push key arg2 |
| 153 | lua_rawget (L, -2); // lookup key in __propget |
| 154 | lua_remove (L, -2); // remove __propget |
| 155 | if (lua_iscfunction (L, -1)) // ensure its a cfunction |
| 156 | { |
| 157 | lua_remove (L, -2); // remove metatable |
| 158 | lua_pushvalue (L, 1); // push class arg1 |
| 159 | lua_call (L, 1, 1); |
| 160 | result = 1; |
| 161 | break; |
| 162 | } |
| 163 | else if (lua_isnil (L, -1)) |
| 164 | { |
| 165 | lua_pop (L, 1); |
| 166 | } |
| 167 | else |
| 168 | { |
| 169 | lua_pop (L, 2); |
| 170 | |
| 171 | // We only put cfunctions into __propget. |
| 172 | throw std::logic_error ("not a cfunction"); |
| 173 | } |
| 174 | } |
| 175 | else |
| 176 | { |
| 177 | lua_pop (L, 2); |
| 178 | |
| 179 | // __propget is missing, or not a table. |
| 180 | throw std::logic_error ("missing __propget table"); |
| 181 | } |
| 182 | |
| 183 | // Repeat the lookup in the __parent metafield, |
| 184 | // or return nil if the field doesn't exist. |
| 185 | rawgetfield (L, -1, "__parent"); |
| 186 | if (lua_istable (L, -1)) |
| 187 | { |
| 188 | // Remove metatable and repeat the search in __parent. |
| 189 | lua_remove (L, -2); |
| 190 | } |
| 191 | else if (lua_isnil (L, -1)) |
| 192 | { |
| 193 | result = 1; |
| 194 | break; |
| 195 | } |
| 196 | else |
| 197 | { |
| 198 | lua_pop (L, 2); |
| 199 | |
| 200 | throw std::logic_error ("__parent is not a table"); |
| 201 | } |
| 202 | } |
| 203 | |
| 204 | return result; |
| 205 | } |
| 206 | |
| 207 | //-------------------------------------------------------------------------- |
| 208 | /** |
| 209 | __newindex metamethod for classes. |
| 210 | |
| 211 | This supports writable variables and properties on class objects. The |
| 212 | corresponding object is passed in the first parameter to the set function. |
| 213 | */ |
| 214 | static int newindexMetaMethod (lua_State* L) |
| 215 | { |
| 216 | int result = 0; |
| 217 | |
| 218 | lua_getmetatable (L, 1); |
| 219 | |
| 220 | for (;;) |
| 221 | { |
| 222 | // Check __propset |
| 223 | rawgetfield (L, -1, "__propset"); |
| 224 | if (!lua_isnil (L, -1)) |
| 225 | { |
| 226 | lua_pushvalue (L, 2); |
| 227 | lua_rawget (L, -2); |
| 228 | if (!lua_isnil (L, -1)) |
| 229 | { |
| 230 | // found it, call the setFunction. |
| 231 | assert (lua_isfunction (L, -1)); |
| 232 | lua_pushvalue (L, 1); |
| 233 | lua_pushvalue (L, 3); |
| 234 | lua_call (L, 2, 0); |
| 235 | result = 0; |
| 236 | break; |
| 237 | } |
| 238 | lua_pop (L, 1); |
| 239 | } |
| 240 | lua_pop (L, 1); |
| 241 | |
| 242 | // Repeat the lookup in the __parent metafield. |
| 243 | rawgetfield (L, -1, "__parent"); |
| 244 | if (lua_isnil (L, -1)) |
| 245 | { |
| 246 | // Either the property or __parent must exist. |
| 247 | result = luaL_error (L, |
| 248 | "no member named '%s'", lua_tostring (L, 2)); |
| 249 | } |
| 250 | lua_remove (L, -2); |
| 251 | } |
| 252 | |
| 253 | return result; |
| 254 | } |
| 255 | |
| 256 | //-------------------------------------------------------------------------- |
| 257 | /** |
| 258 | Create the const table. |
| 259 | */ |
| 260 | void createConstTable (char const* name) |
| 261 | { |
| 262 | lua_newtable (L); |
| 263 | lua_pushvalue (L, -1); |
| 264 | lua_setmetatable (L, -2); |
| 265 | lua_pushboolean (L, 1); |
| 266 | lua_rawsetp (L, -2, getIdentityKey ()); |
| 267 | lua_pushstring (L, (std::string ("const ") + name).c_str ()); |
| 268 | rawsetfield (L, -2, "__type"); |
| 269 | lua_pushcfunction (L, &indexMetaMethod); |
| 270 | rawsetfield (L, -2, "__index"); |
| 271 | lua_pushcfunction (L, &newindexMetaMethod); |
| 272 | rawsetfield (L, -2, "__newindex"); |
| 273 | lua_newtable (L); |
| 274 | rawsetfield (L, -2, "__propget"); |
| 275 | |
| 276 | if (Security::hideMetatables ()) |
| 277 | { |
| 278 | lua_pushnil (L); |
| 279 | rawsetfield (L, -2, "__metatable"); |
| 280 | } |
| 281 | } |
| 282 | |
| 283 | //-------------------------------------------------------------------------- |
| 284 | /** |
| 285 | Create the class table. |
| 286 | |
| 287 | The Lua stack should have the const table on top. |
| 288 | */ |
| 289 | void createClassTable (char const* name) |
| 290 | { |
| 291 | lua_newtable (L); |
| 292 | lua_pushvalue (L, -1); |
| 293 | lua_setmetatable (L, -2); |
| 294 | lua_pushboolean (L, 1); |
| 295 | lua_rawsetp (L, -2, getIdentityKey ()); |
| 296 | lua_pushstring (L, name); |
| 297 | rawsetfield (L, -2, "__type"); |
| 298 | lua_pushcfunction (L, &indexMetaMethod); |
| 299 | rawsetfield (L, -2, "__index"); |
| 300 | lua_pushcfunction (L, &newindexMetaMethod); |
| 301 | rawsetfield (L, -2, "__newindex"); |
| 302 | lua_newtable (L); |
| 303 | rawsetfield (L, -2, "__propget"); |
| 304 | lua_newtable (L); |
| 305 | rawsetfield (L, -2, "__propset"); |
| 306 | |
| 307 | lua_pushvalue (L, -2); |
| 308 | rawsetfield (L, -2, "__const"); // point to const table |
| 309 | |
| 310 | lua_pushvalue (L, -1); |
| 311 | rawsetfield (L, -3, "__class"); // point const table to class table |
| 312 | |
| 313 | if (Security::hideMetatables ()) |
| 314 | { |
| 315 | lua_pushnil (L); |
| 316 | rawsetfield (L, -2, "__metatable"); |
| 317 | } |
| 318 | } |
| 319 | |
| 320 | //-------------------------------------------------------------------------- |
| 321 | /** |
| 322 | Create the static table. |
| 323 | |
| 324 | The Lua stack should have: |
| 325 | -1 class table |
| 326 | -2 const table |
| 327 | -3 enclosing namespace |
| 328 | */ |
| 329 | void createStaticTable (char const* name) |
| 330 | { |
| 331 | lua_newtable (L); |
| 332 | lua_newtable (L); |
| 333 | lua_pushvalue (L, -1); |
| 334 | lua_setmetatable (L, -3); |
| 335 | lua_insert (L, -2); |
| 336 | rawsetfield (L, -5, name); |
| 337 | |
| 338 | #if 0 |
| 339 | lua_pushlightuserdata (L, this); |
| 340 | lua_pushcclosure (L, &tostringMetaMethod, 1); |
| 341 | rawsetfield (L, -2, "__tostring"); |
| 342 | #endif |
| 343 | lua_pushcfunction (L, &CFunc::indexMetaMethod); |
| 344 | rawsetfield (L, -2, "__index"); |
| 345 | lua_pushcfunction (L, &CFunc::newindexMetaMethod); |
| 346 | rawsetfield (L, -2, "__newindex"); |
| 347 | lua_newtable (L); |
| 348 | rawsetfield (L, -2, "__propget"); |
| 349 | lua_newtable (L); |
| 350 | rawsetfield (L, -2, "__propset"); |
| 351 | |
| 352 | lua_pushvalue (L, -2); |
| 353 | rawsetfield (L, -2, "__class"); // point to class table |
| 354 | |
| 355 | if (Security::hideMetatables ()) |
| 356 | { |
| 357 | lua_pushnil (L); |
| 358 | rawsetfield (L, -2, "__metatable"); |
| 359 | } |
| 360 | } |
| 361 | |
| 362 | //========================================================================== |
| 363 | /** |
| 364 | lua_CFunction to construct a class object wrapped in a container. |
| 365 | */ |
| 366 | template <class Params, class C> |
| 367 | static int ctorContainerProxy (lua_State* L) |
| 368 | { |
| 369 | typedef typename ContainerTraits <C>::Type T; |
| 370 | ArgList <Params, 2> args (L); |
| 371 | T* const p = Constructor <T, Params>::call (args); |
| 372 | UserdataSharedHelper <C, false>::push (L, p); |
| 373 | return 1; |
| 374 | } |
| 375 | |
| 376 | //-------------------------------------------------------------------------- |
| 377 | /** |
| 378 | lua_CFunction to construct a class object in-place in the userdata. |
| 379 | */ |
| 380 | template <class Params, class T> |
| 381 | static int ctorPlacementProxy (lua_State* L) |
| 382 | { |
| 383 | ArgList <Params, 2> args (L); |
| 384 | Constructor <T, Params>::call (UserdataValue <T>::place (L), args); |
| 385 | return 1; |
| 386 | } |
| 387 | |
| 388 | //-------------------------------------------------------------------------- |
| 389 | /** |
| 390 | Pop the Lua stack. |
| 391 | */ |
| 392 | void pop (int n) const |
| 393 | { |
| 394 | if (m_stackSize >= n && lua_gettop (L) >= n) |
| 395 | { |
| 396 | lua_pop (L, n); |
| 397 | m_stackSize -= n; |
| 398 | } |
| 399 | else |
| 400 | { |
| 401 | throw std::logic_error ("invalid stack"); |
| 402 | } |
| 403 | } |
| 404 | |
| 405 | public: |
| 406 | //-------------------------------------------------------------------------- |
| 407 | explicit ClassBase (lua_State* L_) |
| 408 | : L (L_) |
| 409 | , m_stackSize (0) |
| 410 | { |
| 411 | } |
| 412 | |
| 413 | //-------------------------------------------------------------------------- |
| 414 | /** |
| 415 | Copy Constructor. |
| 416 | */ |
| 417 | ClassBase (ClassBase const& other) |
| 418 | : L (other.L) |
| 419 | , m_stackSize (0) |
| 420 | { |
| 421 | m_stackSize = other.m_stackSize; |
| 422 | other.m_stackSize = 0; |
| 423 | } |
| 424 | |
| 425 | ~ClassBase () |
| 426 | { |
| 427 | pop (m_stackSize); |
| 428 | } |
| 429 | }; |
| 430 | |
| 431 | //============================================================================ |
| 432 | // |
| 433 | // Class |
| 434 | // |
| 435 | //============================================================================ |
| 436 | /** |
| 437 | Provides a class registration in a lua_State. |
| 438 | |
| 439 | After contstruction the Lua stack holds these objects: |
| 440 | -1 static table |
| 441 | -2 class table |
| 442 | -3 const table |
| 443 | -4 (enclosing namespace) |
| 444 | */ |
| 445 | template <class T> |
| 446 | class Class : public ClassBase |
| 447 | { |
| 448 | public: |
| 449 | //========================================================================== |
| 450 | /** |
| 451 | Register a new class or add to an existing class registration. |
| 452 | */ |
| 453 | Class (char const* name, Namespace const* parent) : ClassBase (parent->L) |
| 454 | { |
| 455 | m_stackSize = parent->m_stackSize + 3; |
| 456 | parent->m_stackSize = 0; |
| 457 | |
| 458 | assert (lua_istable (L, -1)); |
| 459 | rawgetfield (L, -1, name); |
| 460 | |
| 461 | if (lua_isnil (L, -1)) |
| 462 | { |
| 463 | lua_pop (L, 1); |
| 464 | |
| 465 | createConstTable (name); |
| 466 | lua_pushcfunction (L, &CFunc::gcMetaMethod <T>); |
| 467 | rawsetfield (L, -2, "__gc"); |
| 468 | |
| 469 | createClassTable (name); |
| 470 | lua_pushcfunction (L, &CFunc::gcMetaMethod <T>); |
| 471 | rawsetfield (L, -2, "__gc"); |
| 472 | |
| 473 | createStaticTable (name); |
| 474 | |
| 475 | // Map T back to its tables. |
| 476 | lua_pushvalue (L, -1); |
| 477 | lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getStaticKey ()); |
| 478 | lua_pushvalue (L, -2); |
| 479 | lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getClassKey ()); |
| 480 | lua_pushvalue (L, -3); |
| 481 | lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getConstKey ()); |
| 482 | } |
| 483 | else |
| 484 | { |
| 485 | rawgetfield (L, -1, "__class"); |
| 486 | rawgetfield (L, -1, "__const"); |
| 487 | |
| 488 | // Reverse the top 3 stack elements |
| 489 | lua_insert (L, -3); |
| 490 | lua_insert (L, -2); |
| 491 | } |
| 492 | } |
| 493 | |
| 494 | //========================================================================== |
| 495 | /** |
| 496 | Derive a new class. |
| 497 | */ |
| 498 | Class (char const* name, Namespace const* parent, void const* const staticKey) |
| 499 | : ClassBase (parent->L) |
| 500 | { |
| 501 | m_stackSize = parent->m_stackSize + 3; |
| 502 | parent->m_stackSize = 0; |
| 503 | |
| 504 | assert (lua_istable (L, -1)); |
| 505 | |
| 506 | createConstTable (name); |
| 507 | lua_pushcfunction (L, &CFunc::gcMetaMethod <T>); |
| 508 | rawsetfield (L, -2, "__gc"); |
| 509 | |
| 510 | createClassTable (name); |
| 511 | lua_pushcfunction (L, &CFunc::gcMetaMethod <T>); |
| 512 | rawsetfield (L, -2, "__gc"); |
| 513 | |
| 514 | createStaticTable (name); |
| 515 | |
| 516 | lua_rawgetp (L, LUA_REGISTRYINDEX, staticKey); |
| 517 | assert (lua_istable (L, -1)); |
| 518 | rawgetfield (L, -1, "__class"); |
| 519 | assert (lua_istable (L, -1)); |
| 520 | rawgetfield (L, -1, "__const"); |
| 521 | assert (lua_istable (L, -1)); |
| 522 | |
| 523 | rawsetfield (L, -6, "__parent"); |
| 524 | rawsetfield (L, -4, "__parent"); |
| 525 | rawsetfield (L, -2, "__parent"); |
| 526 | |
| 527 | lua_pushvalue (L, -1); |
| 528 | lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getStaticKey ()); |
| 529 | lua_pushvalue (L, -2); |
| 530 | lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getClassKey ()); |
| 531 | lua_pushvalue (L, -3); |
| 532 | lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getConstKey ()); |
| 533 | } |
| 534 | |
| 535 | //-------------------------------------------------------------------------- |
| 536 | /** |
| 537 | Continue registration in the enclosing namespace. |
| 538 | */ |
| 539 | Namespace endClass () |
| 540 | { |
| 541 | return Namespace (this); |
| 542 | } |
| 543 | |
| 544 | //-------------------------------------------------------------------------- |
| 545 | /** |
| 546 | Add or replace a static data member. |
| 547 | */ |
| 548 | template <class U> |
| 549 | Class <T>& addStaticData (char const* name, U* pu, bool isWritable = true) |
| 550 | { |
| 551 | assert (lua_istable (L, -1)); |
| 552 | |
| 553 | rawgetfield (L, -1, "__propget"); |
| 554 | assert (lua_istable (L, -1)); |
| 555 | lua_pushlightuserdata (L, pu); |
| 556 | lua_pushcclosure (L, &CFunc::getVariable <U>, 1); |
| 557 | rawsetfield (L, -2, name); |
| 558 | lua_pop (L, 1); |
| 559 | |
| 560 | rawgetfield (L, -1, "__propset"); |
| 561 | assert (lua_istable (L, -1)); |
| 562 | if (isWritable) |
| 563 | { |
| 564 | lua_pushlightuserdata (L, pu); |
| 565 | lua_pushcclosure (L, &CFunc::setVariable <U>, 1); |
| 566 | } |
| 567 | else |
| 568 | { |
| 569 | lua_pushstring (L, name); |
| 570 | lua_pushcclosure (L, &CFunc::readOnlyError, 1); |
| 571 | } |
| 572 | rawsetfield (L, -2, name); |
| 573 | lua_pop (L, 1); |
| 574 | |
| 575 | return *this; |
| 576 | } |
| 577 | |
| 578 | //-------------------------------------------------------------------------- |
| 579 | /** |
| 580 | Add or replace a static property member. |
| 581 | |
| 582 | If the set function is null, the property is read-only. |
| 583 | */ |
| 584 | template <class U> |
| 585 | Class <T>& addStaticProperty (char const* name, U (*get)(), void (*set)(U) = 0) |
| 586 | { |
| 587 | typedef U (*get_t)(); |
| 588 | typedef void (*set_t)(U); |
| 589 | |
| 590 | assert (lua_istable (L, -1)); |
| 591 | |
| 592 | rawgetfield (L, -1, "__propget"); |
| 593 | assert (lua_istable (L, -1)); |
| 594 | new (lua_newuserdata (L, sizeof (get))) get_t (get); |
| 595 | lua_pushcclosure (L, &CFunc::Call <U (*) (void)>::f, 1); |
| 596 | rawsetfield (L, -2, name); |
| 597 | lua_pop (L, 1); |
| 598 | |
| 599 | rawgetfield (L, -1, "__propset"); |
| 600 | assert (lua_istable (L, -1)); |
| 601 | if (set != 0) |
| 602 | { |
| 603 | new (lua_newuserdata (L, sizeof (set))) set_t (set); |
| 604 | lua_pushcclosure (L, &CFunc::Call <void (*) (U)>::f, 1); |
| 605 | } |
| 606 | else |
| 607 | { |
| 608 | lua_pushstring (L, name); |
| 609 | lua_pushcclosure (L, &CFunc::readOnlyError, 1); |
| 610 | } |
| 611 | rawsetfield (L, -2, name); |
| 612 | lua_pop (L, 1); |
| 613 | |
| 614 | return *this; |
| 615 | } |
| 616 | |
| 617 | //-------------------------------------------------------------------------- |
| 618 | /** |
| 619 | Add or replace a static member function. |
| 620 | */ |
| 621 | template <class FP> |
| 622 | Class <T>& addStaticFunction (char const* name, FP const fp) |
| 623 | { |
| 624 | new (lua_newuserdata (L, sizeof (fp))) FP (fp); |
| 625 | lua_pushcclosure (L, &CFunc::Call <FP>::f, 1); |
| 626 | rawsetfield (L, -2, name); |
| 627 | |
| 628 | return *this; |
| 629 | } |
| 630 | |
| 631 | //-------------------------------------------------------------------------- |
| 632 | /** |
| 633 | Add or replace a lua_CFunction. |
| 634 | */ |
| 635 | Class <T>& addStaticCFunction (char const* name, int (*const fp)(lua_State*)) |
| 636 | { |
| 637 | lua_pushcfunction (L, fp); |
| 638 | rawsetfield (L, -2, name); |
| 639 | return *this; |
| 640 | } |
| 641 | |
| 642 | //-------------------------------------------------------------------------- |
| 643 | /** |
| 644 | Add or replace a data member. |
| 645 | */ |
| 646 | template <class U> |
| 647 | Class <T>& addData (char const* name, const U T::* mp, bool isWritable = true) |
| 648 | { |
| 649 | typedef const U T::*mp_t; |
| 650 | |
| 651 | // Add to __propget in class and const tables. |
| 652 | { |
| 653 | rawgetfield (L, -2, "__propget"); |
| 654 | rawgetfield (L, -4, "__propget"); |
| 655 | new (lua_newuserdata (L, sizeof (mp_t))) mp_t (mp); |
| 656 | lua_pushcclosure (L, &CFunc::getProperty <T,U>, 1); |
| 657 | lua_pushvalue (L, -1); |
| 658 | rawsetfield (L, -4, name); |
| 659 | rawsetfield (L, -2, name); |
| 660 | lua_pop (L, 2); |
| 661 | } |
| 662 | |
| 663 | if (isWritable) |
| 664 | { |
| 665 | // Add to __propset in class table. |
| 666 | rawgetfield (L, -2, "__propset"); |
| 667 | assert (lua_istable (L, -1)); |
| 668 | new (lua_newuserdata (L, sizeof (mp_t))) mp_t (mp); |
| 669 | lua_pushcclosure (L, &CFunc::setProperty <T,U>, 1); |
| 670 | rawsetfield (L, -2, name); |
| 671 | lua_pop (L, 1); |
| 672 | } |
| 673 | |
| 674 | return *this; |
| 675 | } |
| 676 | |
| 677 | //-------------------------------------------------------------------------- |
| 678 | /** |
| 679 | Add or replace a property member. |
| 680 | */ |
| 681 | template <class TG, class TS> |
| 682 | Class <T>& addProperty (char const* name, TG (T::* get) () const, void (T::* set) (TS)) |
| 683 | { |
| 684 | // Add to __propget in class and const tables. |
| 685 | { |
| 686 | rawgetfield (L, -2, "__propget"); |
| 687 | rawgetfield (L, -4, "__propget"); |
| 688 | typedef TG (T::*get_t) () const; |
| 689 | new (lua_newuserdata (L, sizeof (get_t))) get_t (get); |
| 690 | lua_pushcclosure (L, &CFunc::CallConstMember <get_t>::f, 1); |
| 691 | lua_pushvalue (L, -1); |
| 692 | rawsetfield (L, -4, name); |
| 693 | rawsetfield (L, -2, name); |
| 694 | lua_pop (L, 2); |
| 695 | } |
| 696 | |
| 697 | { |
| 698 | // Add to __propset in class table. |
| 699 | rawgetfield (L, -2, "__propset"); |
| 700 | assert (lua_istable (L, -1)); |
| 701 | typedef void (T::* set_t) (TS); |
| 702 | new (lua_newuserdata (L, sizeof (set_t))) set_t (set); |
| 703 | lua_pushcclosure (L, &CFunc::CallMember <set_t>::f, 1); |
| 704 | rawsetfield (L, -2, name); |
| 705 | lua_pop (L, 1); |
| 706 | } |
| 707 | |
| 708 | return *this; |
| 709 | } |
| 710 | |
| 711 | // read-only |
| 712 | template <class TG> |
| 713 | Class <T>& addProperty (char const* name, TG (T::* get) () const) |
| 714 | { |
| 715 | // Add to __propget in class and const tables. |
| 716 | rawgetfield (L, -2, "__propget"); |
| 717 | rawgetfield (L, -4, "__propget"); |
| 718 | typedef TG (T::*get_t) () const; |
| 719 | new (lua_newuserdata (L, sizeof (get_t))) get_t (get); |
| 720 | lua_pushcclosure (L, &CFunc::CallConstMember <get_t>::f, 1); |
| 721 | lua_pushvalue (L, -1); |
| 722 | rawsetfield (L, -4, name); |
| 723 | rawsetfield (L, -2, name); |
| 724 | lua_pop (L, 2); |
| 725 | |
| 726 | return *this; |
| 727 | } |
| 728 | |
| 729 | //-------------------------------------------------------------------------- |
| 730 | /** |
| 731 | Add or replace a property member, by proxy. |
| 732 | |
| 733 | When a class is closed for modification and does not provide (or cannot |
| 734 | provide) the function signatures necessary to implement get or set for |
| 735 | a property, this will allow non-member functions act as proxies. |
| 736 | |
| 737 | Both the get and the set functions require a T const* and T* in the first |
| 738 | argument respectively. |
| 739 | */ |
| 740 | template <class TG, class TS> |
| 741 | Class <T>& addProperty (char const* name, TG (*get) (T const*), void (*set) (T*, TS)) |
| 742 | { |
| 743 | // Add to __propget in class and const tables. |
| 744 | { |
| 745 | rawgetfield (L, -2, "__propget"); |
| 746 | rawgetfield (L, -4, "__propget"); |
| 747 | typedef TG (*get_t) (T const*); |
| 748 | new (lua_newuserdata (L, sizeof (get_t))) get_t (get); |
| 749 | lua_pushcclosure (L, &CFunc::Call <get_t>::f, 1); |
| 750 | lua_pushvalue (L, -1); |
| 751 | rawsetfield (L, -4, name); |
| 752 | rawsetfield (L, -2, name); |
| 753 | lua_pop (L, 2); |
| 754 | } |
| 755 | |
| 756 | if (set != 0) |
| 757 | { |
| 758 | // Add to __propset in class table. |
| 759 | rawgetfield (L, -2, "__propset"); |
| 760 | assert (lua_istable (L, -1)); |
| 761 | typedef void (*set_t) (T*, TS); |
| 762 | new (lua_newuserdata (L, sizeof (set_t))) set_t (set); |
| 763 | lua_pushcclosure (L, &CFunc::Call <set_t>::f, 1); |
| 764 | rawsetfield (L, -2, name); |
| 765 | lua_pop (L, 1); |
| 766 | } |
| 767 | |
| 768 | return *this; |
| 769 | } |
| 770 | |
| 771 | // read-only |
| 772 | template <class TG, class TS> |
| 773 | Class <T>& addProperty (char const* name, TG (*get) (T const*)) |
| 774 | { |
| 775 | // Add to __propget in class and const tables. |
| 776 | rawgetfield (L, -2, "__propget"); |
| 777 | rawgetfield (L, -4, "__propget"); |
| 778 | typedef TG (*get_t) (T const*); |
| 779 | new (lua_newuserdata (L, sizeof (get_t))) get_t (get); |
| 780 | lua_pushcclosure (L, &CFunc::Call <get_t>::f, 1); |
| 781 | lua_pushvalue (L, -1); |
| 782 | rawsetfield (L, -4, name); |
| 783 | rawsetfield (L, -2, name); |
| 784 | lua_pop (L, 2); |
| 785 | |
| 786 | return *this; |
| 787 | } |
| 788 | |
| 789 | //-------------------------------------------------------------------------- |
| 790 | /** |
| 791 | Add or replace a member function. |
| 792 | */ |
| 793 | template <class MemFn> |
| 794 | Class <T>& addFunction (char const* name, MemFn mf) |
| 795 | { |
| 796 | CFunc::CallMemberFunctionHelper <MemFn, FuncTraits <MemFn>::isConstMemberFunction>::add (L, name, mf); |
| 797 | return *this; |
| 798 | } |
| 799 | |
| 800 | //-------------------------------------------------------------------------- |
| 801 | /** |
| 802 | Add or replace a member lua_CFunction. |
| 803 | */ |
| 804 | Class <T>& addCFunction (char const* name, int (T::*mfp)(lua_State*)) |
| 805 | { |
| 806 | typedef int (T::*MFP)(lua_State*); |
| 807 | assert (lua_istable (L, -1)); |
| 808 | new (lua_newuserdata (L, sizeof (mfp))) MFP (mfp); |
| 809 | lua_pushcclosure (L, &CFunc::CallMemberCFunction <T>::f, 1); |
| 810 | rawsetfield (L, -3, name); // class table |
| 811 | |
| 812 | return *this; |
| 813 | } |
| 814 | |
| 815 | //-------------------------------------------------------------------------- |
| 816 | /** |
| 817 | Add or replace a const member lua_CFunction. |
| 818 | */ |
| 819 | Class <T>& addCFunction (char const* name, int (T::*mfp)(lua_State*) const) |
| 820 | { |
| 821 | typedef int (T::*MFP)(lua_State*) const; |
| 822 | assert (lua_istable (L, -1)); |
| 823 | new (lua_newuserdata (L, sizeof (mfp))) MFP (mfp); |
| 824 | lua_pushcclosure (L, &CFunc::CallConstMemberCFunction <T>::f, 1); |
| 825 | lua_pushvalue (L, -1); |
| 826 | rawsetfield (L, -5, name); // const table |
| 827 | rawsetfield (L, -3, name); // class table |
| 828 | |
| 829 | return *this; |
| 830 | } |
| 831 | |
| 832 | //-------------------------------------------------------------------------- |
| 833 | /** |
| 834 | Add or replace a primary Constructor. |
| 835 | |
| 836 | The primary Constructor is invoked when calling the class type table |
| 837 | like a function. |
| 838 | |
| 839 | The template parameter should be a function pointer type that matches |
| 840 | the desired Constructor (since you can't take the address of a Constructor |
| 841 | and pass it as an argument). |
| 842 | */ |
| 843 | template <class MemFn, class C> |
| 844 | Class <T>& addConstructor () |
| 845 | { |
| 846 | lua_pushcclosure (L, |
| 847 | &ctorContainerProxy <typename FuncTraits <MemFn>::Params, C>, 0); |
| 848 | rawsetfield(L, -2, "__call"); |
| 849 | |
| 850 | return *this; |
| 851 | } |
| 852 | |
| 853 | template <class MemFn> |
| 854 | Class <T>& addConstructor () |
| 855 | { |
| 856 | lua_pushcclosure (L, |
| 857 | &ctorPlacementProxy <typename FuncTraits <MemFn>::Params, T>, 0); |
| 858 | rawsetfield(L, -2, "__call"); |
| 859 | |
| 860 | return *this; |
| 861 | } |
| 862 | }; |
| 863 | |
| 864 | private: |
| 865 | //---------------------------------------------------------------------------- |
| 866 | /** |
| 867 | Open the global namespace for registrations. |
| 868 | */ |
| 869 | explicit Namespace (lua_State* L_) |
| 870 | : L (L_) |
| 871 | , m_stackSize (0) |
| 872 | { |
| 873 | lua_getglobal (L, "_G"); |
| 874 | ++m_stackSize; |
| 875 | } |
| 876 | |
| 877 | //---------------------------------------------------------------------------- |
| 878 | /** |
| 879 | Open a namespace for registrations. |
| 880 | |
| 881 | The namespace is created if it doesn't already exist. |
| 882 | The parent namespace is at the top of the Lua stack. |
| 883 | */ |
| 884 | Namespace (char const* name, Namespace const* parent) |
| 885 | : L (parent->L) |
| 886 | , m_stackSize (0) |
| 887 | { |
| 888 | m_stackSize = parent->m_stackSize + 1; |
| 889 | parent->m_stackSize = 0; |
| 890 | |
| 891 | assert (lua_istable (L, -1)); |
| 892 | rawgetfield (L, -1, name); |
| 893 | if (lua_isnil (L, -1)) |
| 894 | { |
| 895 | lua_pop (L, 1); |
| 896 | |
| 897 | lua_newtable (L); |
| 898 | lua_pushvalue (L, -1); |
| 899 | lua_setmetatable (L, -2); |
| 900 | lua_pushcfunction (L, &CFunc::indexMetaMethod); |
| 901 | rawsetfield (L, -2, "__index"); |
| 902 | lua_pushcfunction (L, &CFunc::newindexMetaMethod); |
| 903 | rawsetfield (L, -2, "__newindex"); |
| 904 | lua_newtable (L); |
| 905 | rawsetfield (L, -2, "__propget"); |
| 906 | lua_newtable (L); |
| 907 | rawsetfield (L, -2, "__propset"); |
| 908 | lua_pushvalue (L, -1); |
| 909 | rawsetfield (L, -3, name); |
| 910 | #if 0 |
| 911 | lua_pushcfunction (L, &tostringMetaMethod); |
| 912 | rawsetfield (L, -2, "__tostring"); |
| 913 | #endif |
| 914 | } |
| 915 | } |
| 916 | |
| 917 | //---------------------------------------------------------------------------- |
| 918 | /** |
| 919 | Creates a continued registration from a child namespace. |
| 920 | */ |
| 921 | explicit Namespace (Namespace const* child) |
| 922 | : L (child->L) |
| 923 | , m_stackSize (0) |
| 924 | { |
| 925 | m_stackSize = child->m_stackSize - 1; |
| 926 | child->m_stackSize = 1; |
| 927 | child->pop (1); |
| 928 | |
| 929 | // It is not necessary or valid to call |
| 930 | // endNamespace() for the global namespace! |
| 931 | // |
| 932 | assert (m_stackSize != 0); |
| 933 | } |
| 934 | |
| 935 | //---------------------------------------------------------------------------- |
| 936 | /** |
| 937 | Creates a continued registration from a child class. |
| 938 | */ |
| 939 | explicit Namespace (ClassBase const* child) |
| 940 | : L (child->L) |
| 941 | , m_stackSize (0) |
| 942 | { |
| 943 | m_stackSize = child->m_stackSize - 3; |
| 944 | child->m_stackSize = 3; |
| 945 | child->pop (3); |
| 946 | } |
| 947 | |
| 948 | public: |
| 949 | //---------------------------------------------------------------------------- |
| 950 | /** |
| 951 | Copy Constructor. |
| 952 | |
| 953 | Ownership of the stack is transferred to the new object. This happens |
| 954 | when the compiler emits temporaries to hold these objects while chaining |
| 955 | registrations across namespaces. |
| 956 | */ |
| 957 | Namespace (Namespace const& other) : L (other.L) |
| 958 | { |
| 959 | m_stackSize = other.m_stackSize; |
| 960 | other.m_stackSize = 0; |
| 961 | } |
| 962 | |
| 963 | //---------------------------------------------------------------------------- |
| 964 | /** |
| 965 | Closes this namespace registration. |
| 966 | */ |
| 967 | ~Namespace () |
| 968 | { |
| 969 | pop (m_stackSize); |
| 970 | } |
| 971 | |
| 972 | //---------------------------------------------------------------------------- |
| 973 | /** |
| 974 | Open the global namespace. |
| 975 | */ |
| 976 | static Namespace getGlobalNamespace (lua_State* L) |
| 977 | { |
| 978 | return Namespace (L); |
| 979 | } |
| 980 | |
| 981 | //---------------------------------------------------------------------------- |
| 982 | /** |
| 983 | Open a new or existing namespace for registrations. |
| 984 | */ |
| 985 | Namespace beginNamespace (char const* name) |
| 986 | { |
| 987 | return Namespace (name, this); |
| 988 | } |
| 989 | |
| 990 | //---------------------------------------------------------------------------- |
| 991 | /** |
| 992 | Continue namespace registration in the parent. |
| 993 | |
| 994 | Do not use this on the global namespace. |
| 995 | */ |
| 996 | Namespace endNamespace () |
| 997 | { |
| 998 | return Namespace (this); |
| 999 | } |
| 1000 | |
| 1001 | //---------------------------------------------------------------------------- |
| 1002 | /** |
| 1003 | Add or replace a variable. |
| 1004 | */ |
| 1005 | template <class T> |
| 1006 | Namespace& addVariable (char const* name, T* pt, bool isWritable = true) |
| 1007 | { |
| 1008 | assert (lua_istable (L, -1)); |
| 1009 | |
| 1010 | rawgetfield (L, -1, "__propget"); |
| 1011 | assert (lua_istable (L, -1)); |
| 1012 | lua_pushlightuserdata (L, pt); |
| 1013 | lua_pushcclosure (L, &CFunc::getVariable <T>, 1); |
| 1014 | rawsetfield (L, -2, name); |
| 1015 | lua_pop (L, 1); |
| 1016 | |
| 1017 | rawgetfield (L, -1, "__propset"); |
| 1018 | assert (lua_istable (L, -1)); |
| 1019 | if (isWritable) |
| 1020 | { |
| 1021 | lua_pushlightuserdata (L, pt); |
| 1022 | lua_pushcclosure (L, &CFunc::setVariable <T>, 1); |
| 1023 | } |
| 1024 | else |
| 1025 | { |
| 1026 | lua_pushstring (L, name); |
| 1027 | lua_pushcclosure (L, &CFunc::readOnlyError, 1); |
| 1028 | } |
| 1029 | rawsetfield (L, -2, name); |
| 1030 | lua_pop (L, 1); |
| 1031 | |
| 1032 | return *this; |
| 1033 | } |
| 1034 | |
| 1035 | //---------------------------------------------------------------------------- |
| 1036 | /** |
| 1037 | Add or replace a property. |
| 1038 | |
| 1039 | If the set function is omitted or null, the property is read-only. |
| 1040 | */ |
| 1041 | template <class TG, class TS> |
| 1042 | Namespace& addProperty (char const* name, TG (*get) (), void (*set)(TS) = 0) |
| 1043 | { |
| 1044 | assert (lua_istable (L, -1)); |
| 1045 | |
| 1046 | rawgetfield (L, -1, "__propget"); |
| 1047 | assert (lua_istable (L, -1)); |
| 1048 | typedef TG (*get_t) (); |
| 1049 | new (lua_newuserdata (L, sizeof (get_t))) get_t (get); |
| 1050 | lua_pushcclosure (L, &CFunc::Call <TG (*) (void)>::f, 1); |
| 1051 | rawsetfield (L, -2, name); |
| 1052 | lua_pop (L, 1); |
| 1053 | |
| 1054 | rawgetfield (L, -1, "__propset"); |
| 1055 | assert (lua_istable (L, -1)); |
| 1056 | if (set != 0) |
| 1057 | { |
| 1058 | typedef void (*set_t) (TS); |
| 1059 | new (lua_newuserdata (L, sizeof (set_t))) set_t (set); |
| 1060 | lua_pushcclosure (L, &CFunc::Call <void (*) (TS)>::f, 1); |
| 1061 | } |
| 1062 | else |
| 1063 | { |
| 1064 | lua_pushstring (L, name); |
| 1065 | lua_pushcclosure (L, &CFunc::readOnlyError, 1); |
| 1066 | } |
| 1067 | rawsetfield (L, -2, name); |
| 1068 | lua_pop (L, 1); |
| 1069 | |
| 1070 | return *this; |
| 1071 | } |
| 1072 | |
| 1073 | //---------------------------------------------------------------------------- |
| 1074 | /** |
| 1075 | Add or replace a free function. |
| 1076 | */ |
| 1077 | template <class FP> |
| 1078 | Namespace& addFunction (char const* name, FP const fp) |
| 1079 | { |
| 1080 | assert (lua_istable (L, -1)); |
| 1081 | |
| 1082 | new (lua_newuserdata (L, sizeof (fp))) FP (fp); |
| 1083 | lua_pushcclosure (L, &CFunc::Call <FP>::f, 1); |
| 1084 | rawsetfield (L, -2, name); |
| 1085 | |
| 1086 | return *this; |
| 1087 | } |
| 1088 | |
| 1089 | //---------------------------------------------------------------------------- |
| 1090 | /** |
| 1091 | Add or replace a lua_CFunction. |
| 1092 | */ |
| 1093 | Namespace& addCFunction (char const* name, int (*const fp)(lua_State*)) |
| 1094 | { |
| 1095 | lua_pushcfunction (L, fp); |
| 1096 | rawsetfield (L, -2, name); |
| 1097 | |
| 1098 | return *this; |
| 1099 | } |
| 1100 | |
| 1101 | //---------------------------------------------------------------------------- |
| 1102 | /** |
| 1103 | Open a new or existing class for registrations. |
| 1104 | */ |
| 1105 | template <class T> |
| 1106 | Class <T> beginClass (char const* name) |
| 1107 | { |
| 1108 | return Class <T> (name, this); |
| 1109 | } |
| 1110 | |
| 1111 | //---------------------------------------------------------------------------- |
| 1112 | /** |
| 1113 | Derive a new class for registrations. |
| 1114 | |
| 1115 | To continue registrations for the class later, use beginClass(). |
| 1116 | Do not call deriveClass() again. |
| 1117 | */ |
| 1118 | template <class T, class U> |
| 1119 | Class <T> deriveClass (char const* name) |
| 1120 | { |
| 1121 | return Class <T> (name, this, ClassInfo <U>::getStaticKey ()); |
| 1122 | } |
| 1123 | }; |
| 1124 | |
| 1125 | //------------------------------------------------------------------------------ |
| 1126 | /** |
| 1127 | Retrieve the global namespace. |
| 1128 | |
| 1129 | It is recommended to put your namespace inside the global namespace, and |
| 1130 | then add your classes and functions to it, rather than adding many classes |
| 1131 | and functions directly to the global namespace. |
| 1132 | */ |
| 1133 | inline Namespace getGlobalNamespace (lua_State* L) |
| 1134 | { |
| 1135 | return Namespace::getGlobalNamespace (L); |
| 1136 | } |
trunk/3rdparty/luabridge/Source/LuaBridge/detail/Userdata.h
| r0 | r242832 | |
| 1 | //------------------------------------------------------------------------------ |
| 2 | /* |
| 3 | https://github.com/vinniefalco/LuaBridge |
| 4 | |
| 5 | Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com> |
| 6 | |
| 7 | License: The MIT License (http://www.opensource.org/licenses/mit-license.php) |
| 8 | |
| 9 | Permission is hereby granted, free of charge, to any person obtaining a copy |
| 10 | of this software and associated documentation files (the "Software"), to deal |
| 11 | in the Software without restriction, including without limitation the rights |
| 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| 13 | copies of the Software, and to permit persons to whom the Software is |
| 14 | furnished to do so, subject to the following conditions: |
| 15 | |
| 16 | The above copyright notice and this permission notice shall be included in all |
| 17 | copies or substantial portions of the Software. |
| 18 | |
| 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| 25 | SOFTWARE. |
| 26 | */ |
| 27 | //============================================================================== |
| 28 | |
| 29 | //============================================================================== |
| 30 | /** |
| 31 | Return the identity pointer for our lightuserdata tokens. |
| 32 | |
| 33 | LuaBridge metatables are tagged with a security "token." The token is a |
| 34 | lightuserdata created from the identity pointer, used as a key in the |
| 35 | metatable. The value is a boolean = true, although any value could have been |
| 36 | used. |
| 37 | |
| 38 | Because of Lua's dynamic typing and our improvised system of imposing C++ |
| 39 | class structure, there is the possibility that executing scripts may |
| 40 | knowingly or unknowingly cause invalid data to get passed to the C functions |
| 41 | created by LuaBridge. In particular, our security model addresses the |
| 42 | following: |
| 43 | |
| 44 | Notes: |
| 45 | 1. Scripts cannot create a userdata (ignoring the debug lib). |
| 46 | 2. Scripts cannot create a lightuserdata (ignoring the debug lib). |
| 47 | 3. Scripts cannot set the metatable on a userdata. |
| 48 | 4. Our identity key is a unique pointer in the process. |
| 49 | 5. Our metatables have a lightuserdata identity key / value pair. |
| 50 | 6. Our metatables have "__metatable" set to a boolean = false. |
| 51 | 7. Our lightuserdata is unique. |
| 52 | */ |
| 53 | inline void* getIdentityKey () |
| 54 | { |
| 55 | static char value; |
| 56 | return &value; |
| 57 | } |
| 58 | |
| 59 | /** |
| 60 | Interface to a class pointer retrievable from a userdata. |
| 61 | */ |
| 62 | class Userdata |
| 63 | { |
| 64 | protected: |
| 65 | void* m_p; // subclasses must set this |
| 66 | |
| 67 | //-------------------------------------------------------------------------- |
| 68 | /** |
| 69 | Get an untyped pointer to the contained class. |
| 70 | */ |
| 71 | inline void* const getPointer () |
| 72 | { |
| 73 | return m_p; |
| 74 | } |
| 75 | |
| 76 | private: |
| 77 | //-------------------------------------------------------------------------- |
| 78 | /** |
| 79 | Validate and retrieve a Userdata on the stack. |
| 80 | |
| 81 | The Userdata must exactly match the corresponding class table or |
| 82 | const table, or else a Lua error is raised. This is used for the |
| 83 | __gc metamethod. |
| 84 | */ |
| 85 | static Userdata* getExactClass (lua_State* L, |
| 86 | int narg, |
| 87 | void const* classKey) |
| 88 | { |
| 89 | Userdata* ud = 0; |
| 90 | int const index = lua_absindex (L, narg); |
| 91 | |
| 92 | bool mismatch = false; |
| 93 | char const* got = 0; |
| 94 | |
| 95 | lua_rawgetp (L, LUA_REGISTRYINDEX, classKey); |
| 96 | assert (lua_istable (L, -1)); |
| 97 | |
| 98 | // Make sure we have a userdata. |
| 99 | if (!lua_isuserdata (L, index)) |
| 100 | mismatch = true; |
| 101 | |
| 102 | // Make sure it's metatable is ours. |
| 103 | if (!mismatch) |
| 104 | { |
| 105 | lua_getmetatable (L, index); |
| 106 | lua_rawgetp (L, -1, getIdentityKey ()); |
| 107 | if (lua_isboolean (L, -1)) |
| 108 | { |
| 109 | lua_pop (L, 1); |
| 110 | } |
| 111 | else |
| 112 | { |
| 113 | lua_pop (L, 2); |
| 114 | mismatch = true; |
| 115 | } |
| 116 | } |
| 117 | |
| 118 | if (!mismatch) |
| 119 | { |
| 120 | if (lua_rawequal (L, -1, -2)) |
| 121 | { |
| 122 | // Matches class table. |
| 123 | lua_pop (L, 2); |
| 124 | ud = static_cast <Userdata*> (lua_touserdata (L, index)); |
| 125 | } |
| 126 | else |
| 127 | { |
| 128 | rawgetfield (L, -2, "__const"); |
| 129 | if (lua_rawequal (L, -1, -2)) |
| 130 | { |
| 131 | // Matches const table |
| 132 | lua_pop (L, 3); |
| 133 | ud = static_cast <Userdata*> (lua_touserdata (L, index)); |
| 134 | } |
| 135 | else |
| 136 | { |
| 137 | // Mismatch, but its one of ours so get a type name. |
| 138 | rawgetfield (L, -2, "__type"); |
| 139 | lua_insert (L, -4); |
| 140 | lua_pop (L, 2); |
| 141 | got = lua_tostring (L, -2); |
| 142 | mismatch = true; |
| 143 | } |
| 144 | } |
| 145 | } |
| 146 | |
| 147 | if (mismatch) |
| 148 | { |
| 149 | rawgetfield (L, -1, "__type"); |
| 150 | assert (lua_type (L, -1) == LUA_TSTRING); |
| 151 | char const* const expected = lua_tostring (L, -1); |
| 152 | |
| 153 | if (got == 0) |
| 154 | got = lua_typename (L, lua_type (L, index)); |
| 155 | |
| 156 | char const* const msg = lua_pushfstring ( |
| 157 | L, "%s expected, got %s", expected, got); |
| 158 | |
| 159 | if (narg > 0) |
| 160 | luaL_argerror (L, narg, msg); |
| 161 | else |
| 162 | lua_error (L); |
| 163 | } |
| 164 | |
| 165 | return ud; |
| 166 | } |
| 167 | |
| 168 | //-------------------------------------------------------------------------- |
| 169 | /** |
| 170 | Validate and retrieve a Userdata on the stack. |
| 171 | |
| 172 | The Userdata must be derived from or the same as the given base class, |
| 173 | identified by the key. If canBeConst is false, generates an error if |
| 174 | the resulting Userdata represents to a const object. We do the type check |
| 175 | first so that the error message is informative. |
| 176 | */ |
| 177 | static Userdata* getClass (lua_State* L, |
| 178 | int index, |
| 179 | void const* baseClassKey, |
| 180 | bool canBeConst) |
| 181 | { |
| 182 | assert (index > 0); |
| 183 | Userdata* ud = 0; |
| 184 | |
| 185 | bool mismatch = false; |
| 186 | char const* got = 0; |
| 187 | |
| 188 | lua_rawgetp (L, LUA_REGISTRYINDEX, baseClassKey); |
| 189 | assert (lua_istable (L, -1)); |
| 190 | |
| 191 | // Make sure we have a userdata. |
| 192 | if (lua_isuserdata (L, index)) |
| 193 | { |
| 194 | // Make sure it's metatable is ours. |
| 195 | lua_getmetatable (L, index); |
| 196 | lua_rawgetp (L, -1, getIdentityKey ()); |
| 197 | if (lua_isboolean (L, -1)) |
| 198 | { |
| 199 | lua_pop (L, 1); |
| 200 | |
| 201 | // If __const is present, object is NOT const. |
| 202 | rawgetfield (L, -1, "__const"); |
| 203 | assert (lua_istable (L, -1) || lua_isnil (L, -1)); |
| 204 | bool const isConst = lua_isnil (L, -1); |
| 205 | lua_pop (L, 1); |
| 206 | |
| 207 | // Replace the class table with the const table if needed. |
| 208 | if (isConst) |
| 209 | { |
| 210 | rawgetfield (L, -2, "__const"); |
| 211 | assert (lua_istable (L, -1)); |
| 212 | lua_replace (L, -3); |
| 213 | } |
| 214 | |
| 215 | for (;;) |
| 216 | { |
| 217 | if (lua_rawequal (L, -1, -2)) |
| 218 | { |
| 219 | lua_pop (L, 2); |
| 220 | |
| 221 | // Match, now check const-ness. |
| 222 | if (isConst && !canBeConst) |
| 223 | { |
| 224 | luaL_argerror (L, index, "cannot be const"); |
| 225 | } |
| 226 | else |
| 227 | { |
| 228 | ud = static_cast <Userdata*> (lua_touserdata (L, index)); |
| 229 | break; |
| 230 | } |
| 231 | } |
| 232 | else |
| 233 | { |
| 234 | // Replace current metatable with it's base class. |
| 235 | rawgetfield (L, -1, "__parent"); |
| 236 | /* |
| 237 | ud |
| 238 | class metatable |
| 239 | ud metatable |
| 240 | ud __parent (nil) |
| 241 | */ |
| 242 | |
| 243 | if (lua_isnil (L, -1)) |
| 244 | { |
| 245 | lua_remove (L, -1); |
| 246 | // Mismatch, but its one of ours so get a type name. |
| 247 | rawgetfield (L, -1, "__type"); |
| 248 | lua_insert (L, -3); |
| 249 | lua_pop (L, 1); |
| 250 | got = lua_tostring (L, -2); |
| 251 | mismatch = true; |
| 252 | break; |
| 253 | } |
| 254 | else |
| 255 | { |
| 256 | lua_remove (L, -2); |
| 257 | } |
| 258 | } |
| 259 | } |
| 260 | } |
| 261 | else |
| 262 | { |
| 263 | lua_pop (L, 2); |
| 264 | mismatch = true; |
| 265 | } |
| 266 | } |
| 267 | else |
| 268 | { |
| 269 | mismatch = true; |
| 270 | } |
| 271 | |
| 272 | if (mismatch) |
| 273 | { |
| 274 | assert (lua_type (L, -1) == LUA_TTABLE); |
| 275 | rawgetfield (L, -1, "__type"); |
| 276 | assert (lua_type (L, -1) == LUA_TSTRING); |
| 277 | char const* const expected = lua_tostring (L, -1); |
| 278 | |
| 279 | if (got == 0) |
| 280 | got = lua_typename (L, lua_type (L, index)); |
| 281 | |
| 282 | char const* const msg = lua_pushfstring ( |
| 283 | L, "%s expected, got %s", expected, got); |
| 284 | |
| 285 | luaL_argerror (L, index, msg); |
| 286 | } |
| 287 | |
| 288 | return ud; |
| 289 | } |
| 290 | |
| 291 | public: |
| 292 | virtual ~Userdata () { } |
| 293 | |
| 294 | //-------------------------------------------------------------------------- |
| 295 | /** |
| 296 | Returns the Userdata* if the class on the Lua stack matches. |
| 297 | |
| 298 | If the class does not match, a Lua error is raised. |
| 299 | */ |
| 300 | template <class T> |
| 301 | static inline Userdata* getExact (lua_State* L, int index) |
| 302 | { |
| 303 | return getExactClass (L, index, ClassInfo <T>::getClassKey ()); |
| 304 | } |
| 305 | |
| 306 | //-------------------------------------------------------------------------- |
| 307 | /** |
| 308 | Get a pointer to the class from the Lua stack. |
| 309 | |
| 310 | If the object is not the class or a subclass, or it violates the |
| 311 | const-ness, a Lua error is raised. |
| 312 | */ |
| 313 | template <class T> |
| 314 | static inline T* get (lua_State* L, int index, bool canBeConst) |
| 315 | { |
| 316 | if (lua_isnil (L, index)) |
| 317 | return 0; |
| 318 | else |
| 319 | return static_cast <T*> (getClass (L, index, |
| 320 | ClassInfo <T>::getClassKey (), canBeConst)->getPointer ()); |
| 321 | } |
| 322 | }; |
| 323 | |
| 324 | //---------------------------------------------------------------------------- |
| 325 | /** |
| 326 | Wraps a class object stored in a Lua userdata. |
| 327 | |
| 328 | The lifetime of the object is managed by Lua. The object is constructed |
| 329 | inside the userdata using placement new. |
| 330 | */ |
| 331 | template <class T> |
| 332 | class UserdataValue : public Userdata |
| 333 | { |
| 334 | private: |
| 335 | UserdataValue <T> (UserdataValue <T> const&); |
| 336 | UserdataValue <T> operator= (UserdataValue <T> const&); |
| 337 | |
| 338 | char m_storage [sizeof (T)]; |
| 339 | |
| 340 | inline T* getObject () |
| 341 | { |
| 342 | // If this fails to compile it means you forgot to provide |
| 343 | // a Container specialization for your container! |
| 344 | // |
| 345 | return reinterpret_cast <T*> (&m_storage [0]); |
| 346 | } |
| 347 | |
| 348 | private: |
| 349 | /** |
| 350 | Used for placement construction. |
| 351 | */ |
| 352 | UserdataValue () |
| 353 | { |
| 354 | m_p = getObject (); |
| 355 | } |
| 356 | |
| 357 | ~UserdataValue () |
| 358 | { |
| 359 | getObject ()->~T (); |
| 360 | } |
| 361 | |
| 362 | public: |
| 363 | /** |
| 364 | Push a T via placement new. |
| 365 | |
| 366 | The caller is responsible for calling placement new using the |
| 367 | returned uninitialized storage. |
| 368 | */ |
| 369 | static void* place (lua_State* const L) |
| 370 | { |
| 371 | UserdataValue <T>* const ud = new ( |
| 372 | lua_newuserdata (L, sizeof (UserdataValue <T>))) UserdataValue <T> (); |
| 373 | lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getClassKey ()); |
| 374 | // If this goes off it means you forgot to register the class! |
| 375 | assert (lua_istable (L, -1)); |
| 376 | lua_setmetatable (L, -2); |
| 377 | return ud->getPointer (); |
| 378 | } |
| 379 | |
| 380 | /** |
| 381 | Push T via copy construction from U. |
| 382 | */ |
| 383 | template <class U> |
| 384 | static inline void push (lua_State* const L, U const& u) |
| 385 | { |
| 386 | new (place (L)) U (u); |
| 387 | } |
| 388 | }; |
| 389 | |
| 390 | //---------------------------------------------------------------------------- |
| 391 | /** |
| 392 | Wraps a pointer to a class object inside a Lua userdata. |
| 393 | |
| 394 | The lifetime of the object is managed by C++. |
| 395 | */ |
| 396 | class UserdataPtr : public Userdata |
| 397 | { |
| 398 | private: |
| 399 | UserdataPtr (UserdataPtr const&); |
| 400 | UserdataPtr operator= (UserdataPtr const&); |
| 401 | |
| 402 | private: |
| 403 | /** Push non-const pointer to object using metatable key. |
| 404 | */ |
| 405 | static void push (lua_State* L, void* const p, void const* const key) |
| 406 | { |
| 407 | if (p) |
| 408 | { |
| 409 | new (lua_newuserdata (L, sizeof (UserdataPtr))) UserdataPtr (p); |
| 410 | lua_rawgetp (L, LUA_REGISTRYINDEX, key); |
| 411 | // If this goes off it means you forgot to register the class! |
| 412 | assert (lua_istable (L, -1)); |
| 413 | lua_setmetatable (L, -2); |
| 414 | } |
| 415 | else |
| 416 | { |
| 417 | lua_pushnil (L); |
| 418 | } |
| 419 | } |
| 420 | |
| 421 | /** Push const pointer to object using metatable key. |
| 422 | */ |
| 423 | static void push (lua_State* L, void const* const p, void const* const key) |
| 424 | { |
| 425 | if (p) |
| 426 | { |
| 427 | new (lua_newuserdata (L, sizeof (UserdataPtr))) |
| 428 | UserdataPtr (const_cast <void*> (p)); |
| 429 | lua_rawgetp (L, LUA_REGISTRYINDEX, key); |
| 430 | // If this goes off it means you forgot to register the class! |
| 431 | assert (lua_istable (L, -1)); |
| 432 | lua_setmetatable (L, -2); |
| 433 | } |
| 434 | else |
| 435 | { |
| 436 | lua_pushnil (L); |
| 437 | } |
| 438 | } |
| 439 | |
| 440 | explicit UserdataPtr (void* const p) |
| 441 | { |
| 442 | m_p = p; |
| 443 | |
| 444 | // Can't construct with a null pointer! |
| 445 | // |
| 446 | assert (m_p != 0); |
| 447 | } |
| 448 | |
| 449 | public: |
| 450 | /** Push non-const pointer to object. |
| 451 | */ |
| 452 | template <class T> |
| 453 | static inline void push (lua_State* const L, T* const p) |
| 454 | { |
| 455 | if (p) |
| 456 | push (L, p, ClassInfo <T>::getClassKey ()); |
| 457 | else |
| 458 | lua_pushnil (L); |
| 459 | } |
| 460 | |
| 461 | /** Push const pointer to object. |
| 462 | */ |
| 463 | template <class T> |
| 464 | static inline void push (lua_State* const L, T const* const p) |
| 465 | { |
| 466 | if (p) |
| 467 | push (L, p, ClassInfo <T>::getConstKey ()); |
| 468 | else |
| 469 | lua_pushnil (L); |
| 470 | } |
| 471 | }; |
| 472 | |
| 473 | //============================================================================ |
| 474 | /** |
| 475 | Wraps a container thet references a class object. |
| 476 | |
| 477 | The template argument C is the container type, ContainerTraits must be |
| 478 | specialized on C or else a compile error will result. |
| 479 | */ |
| 480 | template <class C> |
| 481 | class UserdataShared : public Userdata |
| 482 | { |
| 483 | private: |
| 484 | UserdataShared (UserdataShared <C> const&); |
| 485 | UserdataShared <C>& operator= (UserdataShared <C> const&); |
| 486 | |
| 487 | typedef typename TypeTraits::removeConst < |
| 488 | typename ContainerTraits <C>::Type>::Type T; |
| 489 | |
| 490 | C m_c; |
| 491 | |
| 492 | private: |
| 493 | ~UserdataShared () |
| 494 | { |
| 495 | } |
| 496 | |
| 497 | public: |
| 498 | /** |
| 499 | Construct from a container to the class or a derived class. |
| 500 | */ |
| 501 | template <class U> |
| 502 | explicit UserdataShared (U const& u) : m_c (u) |
| 503 | { |
| 504 | m_p = const_cast <void*> (reinterpret_cast <void const*> ( |
| 505 | (ContainerTraits <C>::get (m_c)))); |
| 506 | } |
| 507 | |
| 508 | /** |
| 509 | Construct from a pointer to the class or a derived class. |
| 510 | */ |
| 511 | template <class U> |
| 512 | explicit UserdataShared (U* u) : m_c (u) |
| 513 | { |
| 514 | m_p = const_cast <void*> (reinterpret_cast <void const*> ( |
| 515 | (ContainerTraits <C>::get (m_c)))); |
| 516 | } |
| 517 | }; |
| 518 | |
| 519 | //---------------------------------------------------------------------------- |
| 520 | // |
| 521 | // SFINAE helpers. |
| 522 | // |
| 523 | |
| 524 | // non-const objects |
| 525 | template <class C, bool makeObjectConst> |
| 526 | struct UserdataSharedHelper |
| 527 | { |
| 528 | typedef typename TypeTraits::removeConst < |
| 529 | typename ContainerTraits <C>::Type>::Type T; |
| 530 | |
| 531 | static void push (lua_State* L, C const& c) |
| 532 | { |
| 533 | if (ContainerTraits <C>::get (c) != 0) |
| 534 | { |
| 535 | new (lua_newuserdata (L, sizeof (UserdataShared <C>))) UserdataShared <C> (c); |
| 536 | lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getClassKey ()); |
| 537 | // If this goes off it means the class T is unregistered! |
| 538 | assert (lua_istable (L, -1)); |
| 539 | lua_setmetatable (L, -2); |
| 540 | } |
| 541 | else |
| 542 | { |
| 543 | lua_pushnil (L); |
| 544 | } |
| 545 | } |
| 546 | |
| 547 | static void push (lua_State* L, T* const t) |
| 548 | { |
| 549 | if (t) |
| 550 | { |
| 551 | new (lua_newuserdata (L, sizeof (UserdataShared <C>))) UserdataShared <C> (t); |
| 552 | lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getClassKey ()); |
| 553 | // If this goes off it means the class T is unregistered! |
| 554 | assert (lua_istable (L, -1)); |
| 555 | lua_setmetatable (L, -2); |
| 556 | } |
| 557 | else |
| 558 | { |
| 559 | lua_pushnil (L); |
| 560 | } |
| 561 | } |
| 562 | }; |
| 563 | |
| 564 | // const objects |
| 565 | template <class C> |
| 566 | struct UserdataSharedHelper <C, true> |
| 567 | { |
| 568 | typedef typename TypeTraits::removeConst < |
| 569 | typename ContainerTraits <C>::Type>::Type T; |
| 570 | |
| 571 | static void push (lua_State* L, C const& c) |
| 572 | { |
| 573 | if (ContainerTraits <C>::get (c) != 0) |
| 574 | { |
| 575 | new (lua_newuserdata (L, sizeof (UserdataShared <C>))) UserdataShared <C> (c); |
| 576 | lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getConstKey ()); |
| 577 | // If this goes off it means the class T is unregistered! |
| 578 | assert (lua_istable (L, -1)); |
| 579 | lua_setmetatable (L, -2); |
| 580 | } |
| 581 | else |
| 582 | { |
| 583 | lua_pushnil (L); |
| 584 | } |
| 585 | } |
| 586 | |
| 587 | static void push (lua_State* L, T* const t) |
| 588 | { |
| 589 | if (t) |
| 590 | { |
| 591 | new (lua_newuserdata (L, sizeof (UserdataShared <C>))) UserdataShared <C> (t); |
| 592 | lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getConstKey ()); |
| 593 | // If this goes off it means the class T is unregistered! |
| 594 | assert (lua_istable (L, -1)); |
| 595 | lua_setmetatable (L, -2); |
| 596 | } |
| 597 | else |
| 598 | { |
| 599 | lua_pushnil (L); |
| 600 | } |
| 601 | } |
| 602 | }; |
| 603 | |
| 604 | /** |
| 605 | Pass by container. |
| 606 | |
| 607 | The container controls the object lifetime. Typically this will be a |
| 608 | lifetime shared by C++ and Lua using a reference count. Because of type |
| 609 | erasure, containers like std::shared_ptr will not work. Containers must |
| 610 | either be of the intrusive variety, or in the style of the RefCountedPtr |
| 611 | type provided by LuaBridge (that uses a global hash table). |
| 612 | */ |
| 613 | template <class C, bool byContainer> |
| 614 | struct StackHelper |
| 615 | { |
| 616 | static inline void push (lua_State* L, C const& c) |
| 617 | { |
| 618 | UserdataSharedHelper <C, |
| 619 | TypeTraits::isConst <typename ContainerTraits <C>::Type>::value>::push (L, c); |
| 620 | } |
| 621 | |
| 622 | typedef typename TypeTraits::removeConst < |
| 623 | typename ContainerTraits <C>::Type>::Type T; |
| 624 | |
| 625 | static inline C get (lua_State* L, int index) |
| 626 | { |
| 627 | return Userdata::get <T> (L, index, true); |
| 628 | } |
| 629 | }; |
| 630 | |
| 631 | /** |
| 632 | Pass by value. |
| 633 | |
| 634 | Lifetime is managed by Lua. A C++ function which accesses a pointer or |
| 635 | reference to an object outside the activation record in which it was |
| 636 | retrieved may result in undefined behavior if Lua garbage collected it. |
| 637 | */ |
| 638 | template <class T> |
| 639 | struct StackHelper <T, false> |
| 640 | { |
| 641 | static inline void push (lua_State* L, T const& t) |
| 642 | { |
| 643 | UserdataValue <T>::push (L, t); |
| 644 | } |
| 645 | |
| 646 | static inline T const& get (lua_State* L, int index) |
| 647 | { |
| 648 | return *Userdata::get <T> (L, index, true); |
| 649 | } |
| 650 | }; |
| 651 | |
| 652 | //============================================================================== |
| 653 | |
| 654 | /** |
| 655 | Lua stack conversions for class objects passed by value. |
| 656 | */ |
| 657 | template <class T> |
| 658 | struct Stack |
| 659 | { |
| 660 | public: |
| 661 | static inline void push (lua_State* L, T const& t) |
| 662 | { |
| 663 | StackHelper <T, |
| 664 | TypeTraits::isContainer <T>::value>::push (L, t); |
| 665 | } |
| 666 | |
| 667 | static inline T get (lua_State* L, int index) |
| 668 | { |
| 669 | return StackHelper <T, |
| 670 | TypeTraits::isContainer <T>::value>::get (L, index); |
| 671 | } |
| 672 | }; |
| 673 | |
| 674 | //------------------------------------------------------------------------------ |
| 675 | /** |
| 676 | Lua stack conversions for pointers and references to class objects. |
| 677 | |
| 678 | Lifetime is managed by C++. Lua code which remembers a reference to the |
| 679 | value may result in undefined behavior if C++ destroys the object. The |
| 680 | handling of the const and volatile qualifiers happens in UserdataPtr. |
| 681 | */ |
| 682 | |
| 683 | // pointer |
| 684 | template <class T> |
| 685 | struct Stack <T*> |
| 686 | { |
| 687 | static inline void push (lua_State* L, T* const p) |
| 688 | { |
| 689 | UserdataPtr::push (L, p); |
| 690 | } |
| 691 | |
| 692 | static inline T* const get (lua_State* L, int index) |
| 693 | { |
| 694 | return Userdata::get <T> (L, index, false); |
| 695 | } |
| 696 | }; |
| 697 | |
| 698 | // Strips the const off the right side of * |
| 699 | template <class T> |
| 700 | struct Stack <T* const> |
| 701 | { |
| 702 | static inline void push (lua_State* L, T* const p) |
| 703 | { |
| 704 | UserdataPtr::push (L, p); |
| 705 | } |
| 706 | |
| 707 | static inline T* const get (lua_State* L, int index) |
| 708 | { |
| 709 | return Userdata::get <T> (L, index, false); |
| 710 | } |
| 711 | }; |
| 712 | |
| 713 | // pointer to const |
| 714 | template <class T> |
| 715 | struct Stack <T const*> |
| 716 | { |
| 717 | static inline void push (lua_State* L, T const* const p) |
| 718 | { |
| 719 | UserdataPtr::push (L, p); |
| 720 | } |
| 721 | |
| 722 | static inline T const* const get (lua_State* L, int index) |
| 723 | { |
| 724 | return Userdata::get <T> (L, index, true); |
| 725 | } |
| 726 | }; |
| 727 | |
| 728 | // Strips the const off the right side of * |
| 729 | template <class T> |
| 730 | struct Stack <T const* const> |
| 731 | { |
| 732 | static inline void push (lua_State* L, T const* const p) |
| 733 | { |
| 734 | UserdataPtr::push (L, p); |
| 735 | } |
| 736 | |
| 737 | static inline T const* const get (lua_State* L, int index) |
| 738 | { |
| 739 | return Userdata::get <T> (L, index, true); |
| 740 | } |
| 741 | }; |
| 742 | |
| 743 | // reference |
| 744 | template <class T> |
| 745 | struct Stack <T&> |
| 746 | { |
| 747 | static inline void push (lua_State* L, T& t) |
| 748 | { |
| 749 | UserdataPtr::push (L, &t); |
| 750 | } |
| 751 | |
| 752 | static T& get (lua_State* L, int index) |
| 753 | { |
| 754 | T* const t = Userdata::get <T> (L, index, false); |
| 755 | if (!t) |
| 756 | luaL_error (L, "nil passed to reference"); |
| 757 | return *t; |
| 758 | } |
| 759 | }; |
| 760 | |
| 761 | template <class C, bool byContainer> |
| 762 | struct RefStackHelper |
| 763 | { |
| 764 | typedef C return_type; |
| 765 | |
| 766 | static inline void push (lua_State* L, C const& t) |
| 767 | { |
| 768 | UserdataSharedHelper <C, |
| 769 | TypeTraits::isConst <typename ContainerTraits <C>::Type>::value>::push (L, t); |
| 770 | } |
| 771 | |
| 772 | typedef typename TypeTraits::removeConst < |
| 773 | typename ContainerTraits <C>::Type>::Type T; |
| 774 | |
| 775 | static return_type get (lua_State* L, int index) |
| 776 | { |
| 777 | return Userdata::get <T> (L, index, true); |
| 778 | } |
| 779 | }; |
| 780 | |
| 781 | template <class T> |
| 782 | struct RefStackHelper <T, false> |
| 783 | { |
| 784 | typedef T const& return_type; |
| 785 | |
| 786 | static inline void push (lua_State* L, T const& t) |
| 787 | { |
| 788 | UserdataPtr::push (L, &t); |
| 789 | } |
| 790 | |
| 791 | static return_type get (lua_State* L, int index) |
| 792 | { |
| 793 | T const* const t = Userdata::get <T> (L, index, true); |
| 794 | |
| 795 | if (!t) |
| 796 | luaL_error (L, "nil passed to reference"); |
| 797 | return *t; |
| 798 | } |
| 799 | |
| 800 | }; |
| 801 | |
| 802 | // reference to const |
| 803 | template <class T> |
| 804 | struct Stack <T const&> |
| 805 | { |
| 806 | typedef RefStackHelper <T, TypeTraits::isContainer <T>::value> helper_t; |
| 807 | |
| 808 | static inline void push (lua_State* L, T const& t) |
| 809 | { |
| 810 | helper_t::push (L, t); |
| 811 | } |
| 812 | |
| 813 | static typename helper_t::return_type get (lua_State* L, int index) |
| 814 | { |
| 815 | return helper_t::get (L, index); |
| 816 | } |
| 817 | }; |