VTK/Wrapping C++11 Code: Difference between revisions
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. | ||
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 | '''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 | '''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 | '''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 | '''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 | '''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 | '''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 | '''Done.''' | ||
===Trailer noexcept()=== | ===Trailer noexcept()=== | ||
Line 52: | Line 54: | ||
noexcept ( constant_expression ) | noexcept ( constant_expression ) | ||
'''Done | '''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 | '''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 | '''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 | '''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 | '''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 | '''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 | '''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 | '''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 | '''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 | '''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 | '''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 | '''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 | '''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 | '''Done.''' | ||
===C99 features=== | ===C99 features=== | ||
Line 136: | Line 138: | ||
Qualifer _Atomic. | Qualifer _Atomic. | ||
'''Done | '''Done.''' | ||
===Extern Templates=== | ===Extern Templates=== | ||
New "extern template" template declaration. | New "extern template" template declaration. | ||
'''Done | '''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 | '''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.