VTK/Wrapping C++11 Code: Difference between revisions

From KitwarePublic
< VTK
Jump to navigationJump to search
No edit summary
No edit summary
Line 3: Line 3:
Most VTK code follows the C++03 standard, and the oldest supported compiler is (I believe) Visual Studio .NET 2003.  However, all VTK code is also compatible with C++11, and in fact VTK uses some features of C99 that were incorporated into C++11.  Users of VTK have already begun moving their own code to C++11.
Most VTK code follows the C++03 standard, and the oldest supported compiler is (I believe) Visual Studio .NET 2003.  However, all VTK code is also compatible with C++11, and in fact VTK uses some features of C99 that were incorporated into C++11.  Users of VTK have already begun moving their own code to C++11.


Currently the wrappers are unable to parse any C++11 code that appears in the header files, but this will be changing soon. The following is a list of various new C++11 features to be supported.  I will be adding these features to my [http://github.com/dgobbi/WrapVTK WrapVTK] project before moving them into VTK proper.
The following is a list of various new C++11 features to be supported.  I will be adding these features to my [http://github.com/dgobbi/WrapVTK WrapVTK] project before moving them into VTK proper.
 
'''Current status: awaiting review.''' 17 Nov 2013


===Closing angle brackets===
===Closing angle brackets===
Support code like std::vector<std::vector<int>> without requiring spaces between > and >.
Support code like std::vector<std::vector<int>> without requiring spaces between > and >.


'''Done in WrapVTK.'''
'''Done.'''


===Rvalue references===
===Rvalue references===
Use of "&&" to indicate an rvalue reference.  As long as it is only used in assignment operators and copy constructors, I don't think the wrappers have to worry about the semantics, they just have to parse it.  Are there bits available to represent it?  It requires a modifier for "ref", and "const ref" already exists, so just as we use the CONST qualifier bit for "const &", we can have an "RVALUE" qualifier bit for "&&".
Use of "&&" to indicate an rvalue reference.  As long as it is only used in assignment operators and copy constructors, I don't think the wrappers have to worry about the semantics, they just have to parse it.  Are there bits available to represent it?  It requires a modifier for "ref", and "const ref" already exists, so just as we use the CONST qualifier bit for "const &", we can have an "RVALUE" qualifier bit for "&&".


'''Done in WrapVTK.'''
'''Done.'''


===The constexpr keyword===
===The constexpr keyword===
Initially, this keyword can be ignored (until proper constant expression parsing is implemented).
Initially, this keyword can be ignored (until proper constant expression parsing is implemented).


'''Done in WrapVTK.'''
'''Done.'''


===New static_assert()===
===New static_assert()===
Uses of static_assert() can easily be removed by the lexer, though removing it in the parser is possible, too, with a little extra work.
Uses of static_assert() can easily be removed by the lexer, though removing it in the parser is possible, too, with a little extra work.


'''Done in WrapVTK.'''
'''Done.'''


===Keyword decltype()===
===Keyword decltype()===
Line 29: Line 31:
This provides the type of the expression in the parentheses.  I can defer the type deduction (for templates, the type deduction will have to be deferred anyway).  Deducing the type will require a complete constant_expression parser, which I don't have yet.  I will probably implement the constant_expression parser as its own recursive descent parser, rather than implement it as part of the main yacc parser.
This provides the type of the expression in the parentheses.  I can defer the type deduction (for templates, the type deduction will have to be deferred anyway).  Deducing the type will require a complete constant_expression parser, which I don't have yet.  I will probably implement the constant_expression parser as its own recursive descent parser, rather than implement it as part of the main yacc parser.


'''Done in WrapVTK.'''
'''Done.'''


===Method declaration with trailing return type===
===Method declaration with trailing return type===
Line 37: Line 39:
   auto add(const Lhs &lhs, const Rhs &rhs) -> decltype(lhs+rhs) {return lhs + rhs;}
   auto add(const Lhs &lhs, const Rhs &rhs) -> decltype(lhs+rhs) {return lhs + rhs;}


'''Done in WrapVTK.'''
'''Done.'''


===Trailers final and override===
===Trailers final and override===
Line 44: Line 46:
Note that "final" can be used in a class definition immediately after the class_id to declare that the class cannot be subclassed.
Note that "final" can be used in a class definition immediately after the class_id to declare that the class cannot be subclassed.


'''Done in WrapVTK.'''
'''Done.'''


===Trailer noexcept()===
===Trailer noexcept()===
Line 52: Line 54:
  noexcept ( constant_expression )
  noexcept ( constant_expression )


'''Done in WrapVTK.'''
'''Done.'''


===Function bodies default, delete===
===Function bodies default, delete===
Similar in syntax to the "= 0" body for pure virtual methods.  In C++11, any method that the compiler can auto-generate (default constructor, copy constructor, destructor, assignment operator) can have its body replaced by "= default;" or "= delete;".  The wrappers must honor these settings when it auto-generates these methods.
Similar in syntax to the "= 0" body for pure virtual methods.  In C++11, any method that the compiler can auto-generate (default constructor, copy constructor, destructor, assignment operator) can have its body replaced by "= default;" or "= delete;".  The wrappers must honor these settings when it auto-generates these methods.


'''Done in WrapVTK.'''
'''Done.'''


===Auto variable type===
===Auto variable type===
For variables declared with "auto", the type will have to be deduced, in much the same way as is done with macro constants.
For variables declared with "auto", the type will have to be deduced, in much the same way as is done with macro constants.


'''Done in WrapVTK.'''
'''Done.'''


===New literal nullptr===
===New literal nullptr===
May require a new keyword, and a type constant for nullptr_t.
May require a new keyword, and a type constant for nullptr_t.


'''Done in WrapVTK.'''
'''Done.'''


===New string literal types===
===New string literal types===
Prefixes "R", "u8", "u", "U".  Plus, the prefix "L" is not implemented yet.
Prefixes "R", "u8", "u", "U".  Plus, the prefix "L" is not implemented yet.


'''Done in WrapVTK. Caveat: raw strings supported everywhere except for in preprocessor directives.'''
'''Done. Caveat: raw strings supported everywhere except for in preprocessor directives.'''


===New char types===
===New char types===
These are char16_t, char32_t, and also the pre-C++11 type wchar_t.  Are these primitive types, or are they typdefs to a unique type, similar to nullptr_t?  Or typedefs to a non-unique type, like size_t?  I believe that wchar_t, at least, is required to be a primitive type.  Unlike wchar_t and char, we at least know that char16_t and char32_t are unsigned.  Also, in the C++11 standard (though not necessarily in pre-standard compilers) they are primitive types.
These are char16_t, char32_t, and also the pre-C++11 type wchar_t.  Are these primitive types, or are they typdefs to a unique type, similar to nullptr_t?  Or typedefs to a non-unique type, like size_t?  I believe that wchar_t, at least, is required to be a primitive type.  Unlike wchar_t and char, we at least know that char16_t and char32_t are unsigned.  Also, in the C++11 standard (though not necessarily in pre-standard compilers) they are primitive types.


'''Done in WrapVTK.'''
'''Done.'''


===New string types===
===New string types===
Line 87: Line 89:
Tokenization of literals will have to be extended, and the new operator"" will have to be added.  Capturing the literals as strings will be easy, but when I implement a constant_expression parser, these will have to be parsed whenever they are declared with constexpr.
Tokenization of literals will have to be extended, and the new operator"" will have to be added.  Capturing the literals as strings will be easy, but when I implement a constant_expression parser, these will have to be parsed whenever they are declared with constexpr.


'''Done in WrapVTK.'''
'''Done.'''


===New enum classes===
===New enum classes===
Tricky, but they can still be considered to be enums. I'll have to add a type member to EnumInfo.  The grammar will also have to allow for forward declaration of enums.
Tricky, but they can still be considered to be enums. I'll have to add a type member to EnumInfo.  The grammar will also have to allow for forward declaration of enums.


'''Done in WrapVTK.'''
'''Done.'''


===The thread_local storage specifier===
===The thread_local storage specifier===
This should be parsed and handled similar to ''static''.
This should be parsed and handled similar to ''static''.


'''Done in WrapVTK.'''
'''Done.'''


===Explicit conversion operators===
===Explicit conversion operators===
Implement "explicit" specifier for conversion operators.  This is already parsed, so it is just a matter of setting the IsExplicit flag when the specifier is present.
Implement "explicit" specifier for conversion operators.  This is already parsed, so it is just a matter of setting the IsExplicit flag when the specifier is present.


'''Done in WrapVTK.'''
'''Done.'''


===Creating type aliases with "using"===
===Creating type aliases with "using"===
Line 111: Line 113:
  using TypedefName = SomeType<OtherType, Second, 5>;
  using TypedefName = SomeType<OtherType, Second, 5>;


'''Done in WrapVTK.'''
'''Done.'''


===Variadic templates===
===Variadic templates===
Line 119: Line 121:
* and, if variadic templates are ever to be wrapped, instantiation
* and, if variadic templates are ever to be wrapped, instantiation


'''Done in WrapVTK.'''
'''Done.'''


===Attributes===
===Attributes===
Attributes of the form <nowiki>[[name]]</nowiki>, <nowiki>[[name(x,y)]]</nowiki>, and <nowiki>alignas(type)</nowiki> will have to be parsed.  A set of attributes can be defined for wrapping hints at some point in the future, but until then attributes can be ignored.  If the attributes are hard to parse, then token sequence "[[" can be defined as a new token (allowing for space between the left brackets).
Attributes of the form <nowiki>[[name]]</nowiki>, <nowiki>[[name(x,y)]]</nowiki>, and <nowiki>alignas(type)</nowiki> will have to be parsed.  A set of attributes can be defined for wrapping hints at some point in the future, but until then attributes can be ignored.  If the attributes are hard to parse, then token sequence "[[" can be defined as a new token (allowing for space between the left brackets).


'''Done in WrapVTK.  Caveat: attributes are simply ignored.'''
'''Done.  Caveat: attributes are simply ignored.'''


===Keyword alignof()===
===Keyword alignof()===
Operator alignof(type), e.g. alignof(int).  It will have to be handled similarly to sizeof(), i.e. not at all until constant expression parsing is implemented.
Operator alignof(type), e.g. alignof(int).  It will have to be handled similarly to sizeof(), i.e. not at all until constant expression parsing is implemented.


'''Done in WrapVTK.'''
'''Done.'''


===C99 features===
===C99 features===
Line 136: Line 138:
Qualifer _Atomic.
Qualifer _Atomic.


'''Done in WrapVTK.'''
'''Done.'''


===Extern Templates===
===Extern Templates===
New "extern template" template declaration.
New "extern template" template declaration.


'''Done in WrapVTK.'''
'''Done.'''


===Lamdas===
===Lamdas===
Line 151: Line 153:
If "..." ends a macro parameter list, then in the body of the macro __VA_ARGS__ should expand to the portion of the argument list that corresponds to the ellipsis.
If "..." ends a macro parameter list, then in the body of the macro __VA_ARGS__ should expand to the portion of the argument list that corresponds to the ellipsis.


'''Done in WrapVTK, plus gcc and MSVC extensions.'''
'''Done, plus gcc and MSVC extensions.'''

Revision as of 06:24, 18 November 2013

The purpose of this page is to track the status of C++11 support in the VTK wrappers.

Most VTK code follows the C++03 standard, and the oldest supported compiler is (I believe) Visual Studio .NET 2003. However, all VTK code is also compatible with C++11, and in fact VTK uses some features of C99 that were incorporated into C++11. Users of VTK have already begun moving their own code to C++11.

The following is a list of various new C++11 features to be supported. I will be adding these features to my WrapVTK project before moving them into VTK proper.

Current status: awaiting review. 17 Nov 2013

Closing angle brackets

Support code like std::vector<std::vector<int>> without requiring spaces between > and >.

Done.

Rvalue references

Use of "&&" to indicate an rvalue reference. As long as it is only used in assignment operators and copy constructors, I don't think the wrappers have to worry about the semantics, they just have to parse it. Are there bits available to represent it? It requires a modifier for "ref", and "const ref" already exists, so just as we use the CONST qualifier bit for "const &", we can have an "RVALUE" qualifier bit for "&&".

Done.

The constexpr keyword

Initially, this keyword can be ignored (until proper constant expression parsing is implemented).

Done.

New static_assert()

Uses of static_assert() can easily be removed by the lexer, though removing it in the parser is possible, too, with a little extra work.

Done.

Keyword decltype()

This provides the type of the expression in the parentheses. I can defer the type deduction (for templates, the type deduction will have to be deferred anyway). Deducing the type will require a complete constant_expression parser, which I don't have yet. I will probably implement the constant_expression parser as its own recursive descent parser, rather than implement it as part of the main yacc parser.

Done.

Method declaration with trailing return type

This is just a new function trailer, it will be easy to implement once decltype() is implemented.

template<class Lhs, class Rhs>
  auto add(const Lhs &lhs, const Rhs &rhs) -> decltype(lhs+rhs) {return lhs + rhs;}

Done.

Trailers final and override

These are trivial to implement because the wrappers can ignore the semantics. Though it might be useful for the wrappers to honor "final". Note: Unlike "throw" and "const", these are not keywords. They should be parsed as identifiers.

Note that "final" can be used in a class definition immediately after the class_id to declare that the class cannot be subclassed.

Done.

Trailer noexcept()

This goes along with the throw() trailer that already exists:

noexcept
noexcept ( constant_expression )

Done.

Function bodies default, delete

Similar in syntax to the "= 0" body for pure virtual methods. In C++11, any method that the compiler can auto-generate (default constructor, copy constructor, destructor, assignment operator) can have its body replaced by "= default;" or "= delete;". The wrappers must honor these settings when it auto-generates these methods.

Done.

Auto variable type

For variables declared with "auto", the type will have to be deduced, in much the same way as is done with macro constants.

Done.

New literal nullptr

May require a new keyword, and a type constant for nullptr_t.

Done.

New string literal types

Prefixes "R", "u8", "u", "U". Plus, the prefix "L" is not implemented yet.

Done. Caveat: raw strings supported everywhere except for in preprocessor directives.

New char types

These are char16_t, char32_t, and also the pre-C++11 type wchar_t. Are these primitive types, or are they typdefs to a unique type, similar to nullptr_t? Or typedefs to a non-unique type, like size_t? I believe that wchar_t, at least, is required to be a primitive type. Unlike wchar_t and char, we at least know that char16_t and char32_t are unsigned. Also, in the C++11 standard (though not necessarily in pre-standard compilers) they are primitive types.

Done.

New string types

The C++11 library defines std::u16string and std::u32string. The wrapper parser recognizes std::string as a special type, but this should not be extended to u16string and u32string. They should not be special-cased within the parser code itself, it should be up to the wrapper back-ends like vtkWrapPython to recognize them and wrap them.

Not done, deferred.

User-defined literal suffixes

Tokenization of literals will have to be extended, and the new operator"" will have to be added. Capturing the literals as strings will be easy, but when I implement a constant_expression parser, these will have to be parsed whenever they are declared with constexpr.

Done.

New enum classes

Tricky, but they can still be considered to be enums. I'll have to add a type member to EnumInfo. The grammar will also have to allow for forward declaration of enums.

Done.

The thread_local storage specifier

This should be parsed and handled similar to static.

Done.

Explicit conversion operators

Implement "explicit" specifier for conversion operators. This is already parsed, so it is just a matter of setting the IsExplicit flag when the specifier is present.

Done.

Creating type aliases with "using"

using FunctionType = void (*)(double);

template <typename Second>
using TypedefName = SomeType<OtherType, Second, 5>;

Done.

Variadic templates

This will involve three pieces:

  • parsing the template parameters
  • parsing the pack expansions
  • and, if variadic templates are ever to be wrapped, instantiation

Done.

Attributes

Attributes of the form [[name]], [[name(x,y)]], and alignas(type) will have to be parsed. A set of attributes can be defined for wrapping hints at some point in the future, but until then attributes can be ignored. If the attributes are hard to parse, then token sequence "[[" can be defined as a new token (allowing for space between the left brackets).

Done. Caveat: attributes are simply ignored.

Keyword alignof()

Operator alignof(type), e.g. alignof(int). It will have to be handled similarly to sizeof(), i.e. not at all until constant expression parsing is implemented.

Done.

C99 features

Specifiers _Alignas(), _Generic(), _Thread_local, _Noreturn.

Qualifer _Atomic.

Done.

Extern Templates

New "extern template" template declaration.

Done.

Lamdas

Lambda will not appear as part of class definitions, so they can be ignored.

Nothing to be done.

Variadic macros

If "..." ends a macro parameter list, then in the body of the macro __VA_ARGS__ should expand to the portion of the argument list that corresponds to the ellipsis.

Done, plus gcc and MSVC extensions.