Skip to content

Commit

Permalink
[C++] Switch to std::any and deprecate antlrcpp::Any
Browse files Browse the repository at this point in the history
  • Loading branch information
jcking committed Dec 6, 2021
1 parent 7da07c7 commit 557620d
Show file tree
Hide file tree
Showing 14 changed files with 33 additions and 201 deletions.
2 changes: 1 addition & 1 deletion runtime/Cpp/runtime/src/RuleContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ size_t RuleContext::getAltNumber() const {
void RuleContext::setAltNumber(size_t /*altNumber*/) {
}

antlrcpp::Any RuleContext::accept(tree::ParseTreeVisitor *visitor) {
std::any RuleContext::accept(tree::ParseTreeVisitor *visitor) {
return visitor->visitChildren(this);
}

Expand Down
2 changes: 1 addition & 1 deletion runtime/Cpp/runtime/src/RuleContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ namespace antlr4 {
*/
virtual void setAltNumber(size_t altNumber);

virtual antlrcpp::Any accept(tree::ParseTreeVisitor *visitor) override;
virtual std::any accept(tree::ParseTreeVisitor *visitor) override;

/// <summary>
/// Print out a whole tree, not just a node, in LISP format
Expand Down
1 change: 1 addition & 0 deletions runtime/Cpp/runtime/src/antlr4-common.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#pragma once

#include <algorithm>
#include <any>
#include <assert.h>
#include <atomic>
#include <chrono>
Expand Down
5 changes: 0 additions & 5 deletions runtime/Cpp/runtime/src/support/Any.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,3 @@
#include "Any.h"

using namespace antlrcpp;

Any::~Any()
{
delete _ptr;
}
166 changes: 1 addition & 165 deletions runtime/Cpp/runtime/src/support/Any.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,172 +9,8 @@

#include "antlr4-common.h"

#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4521) // 'antlrcpp::Any': multiple copy constructors specified
#endif

namespace antlrcpp {

template<class T>
using StorageType = typename std::decay<T>::type;

struct ANTLR4CPP_PUBLIC Any
{
bool isNull() const { return _ptr == nullptr; }
bool isNotNull() const { return _ptr != nullptr; }

Any() : _ptr(nullptr) {
}

Any(Any& that) : _ptr(that.clone()) {
}

Any(Any&& that) : _ptr(that._ptr) {
that._ptr = nullptr;
}

Any(const Any& that) : _ptr(that.clone()) {
}

Any(const Any&& that) : _ptr(that.clone()) {
}

template<typename U>
Any(U&& value) : _ptr(new Derived<StorageType<U>>(std::forward<U>(value))) {
}

template<class U>
bool is() const {
auto derived = getDerived<U>(false);

return derived != nullptr;
}

template<class U>
StorageType<U>& as() {
auto derived = getDerived<U>(true);

return derived->value;
}

template<class U>
const StorageType<U>& as() const {
auto derived = getDerived<U>(true);

return derived->value;
}

template<class U, typename std::enable_if<std::is_copy_constructible<U>::value || std::is_copy_assignable<U>::value>::value>
operator U() {
return as<StorageType<U>>();
}

template<class U, typename std::enable_if<(!std::is_copy_constructible<U>::value && !std::is_copy_assignable<U>::value) && (std::is_move_constructible<U>::value || std::is_move_assignable<U>::value)>::value>
operator U() {
return std::move(as<StorageType<U>>());
}

template<class U, typename std::enable_if<std::is_copy_constructible<U>::value || std::is_copy_assignable<U>::value>::value>
operator const U() const {
return as<const StorageType<U>>();
}

template<class U, typename std::enable_if<!(!std::is_copy_constructible<U>::value && !std::is_copy_assignable<U>::value) && (std::is_move_constructible<U>::value || std::is_move_assignable<U>::value)>::value>
operator const U() const {
return std::move(as<const StorageType<U>>());
}

Any& operator = (const Any& a) {
if (_ptr == a._ptr)
return *this;

auto * old_ptr = _ptr;
_ptr = a.clone();

if (old_ptr)
delete old_ptr;

return *this;
}

Any& operator = (Any&& a) {
if (_ptr == a._ptr)
return *this;

std::swap(_ptr, a._ptr);

return *this;
}

virtual ~Any();

virtual bool equals(const Any& other) const {
return _ptr == other._ptr;
}

private:
struct Base {
virtual ~Base() {};
virtual Base* clone() const = 0;
};

template<typename T>
struct Derived : Base
{
template<typename U> Derived(U&& value_) : value(std::forward<U>(value_)) {
}

T value;

Base* clone() const {
return clone<>();
}

private:
template<int N = 0, typename std::enable_if<N == N && std::is_nothrow_copy_constructible<T>::value, int>::type = 0>
Base* clone() const {
return new Derived<T>(value);
}

template<int N = 0, typename std::enable_if<N == N && !std::is_nothrow_copy_constructible<T>::value, int>::type = 0>
Base* clone() const {
return nullptr;
}

};

Base* clone() const
{
if (_ptr)
return _ptr->clone();
else
return nullptr;
}

template<class U>
Derived<StorageType<U>>* getDerived(bool checkCast) const {
typedef StorageType<U> T;

auto derived = dynamic_cast<Derived<T>*>(_ptr);

if (checkCast && !derived)
throw std::bad_cast();

return derived;
}

Base *_ptr;

};

template<> inline
Any::Any(std::nullptr_t&& ) : _ptr(nullptr) {
}

using Any = std::any;

} // namespace antlrcpp

#ifdef _MSC_VER
#pragma warning(pop)
#endif
20 changes: 10 additions & 10 deletions runtime/Cpp/runtime/src/tree/AbstractParseTreeVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace tree {
public:
/// The default implementation calls <seealso cref="ParseTree#accept"/> on the
/// specified tree.
virtual antlrcpp::Any visit(ParseTree *tree) override {
virtual std::any visit(ParseTree *tree) override {
return tree->accept(this);
}

Expand All @@ -32,15 +32,15 @@ namespace tree {
* the tree structure. Visitors that modify the tree should override this
* method to behave properly in respect to the specific algorithm in use.</p>
*/
virtual antlrcpp::Any visitChildren(ParseTree *node) override {
antlrcpp::Any result = defaultResult();
virtual std::any visitChildren(ParseTree *node) override {
std::any result = defaultResult();
size_t n = node->children.size();
for (size_t i = 0; i < n; i++) {
if (!shouldVisitNextChild(node, result)) {
break;
}

antlrcpp::Any childResult = node->children[i]->accept(this);
std::any childResult = node->children[i]->accept(this);
result = aggregateResult(result, childResult);
}

Expand All @@ -49,13 +49,13 @@ namespace tree {

/// The default implementation returns the result of
/// <seealso cref="#defaultResult defaultResult"/>.
virtual antlrcpp::Any visitTerminal(TerminalNode * /*node*/) override {
virtual std::any visitTerminal(TerminalNode * /*node*/) override {
return defaultResult();
}

/// The default implementation returns the result of
/// <seealso cref="#defaultResult defaultResult"/>.
virtual antlrcpp::Any visitErrorNode(ErrorNode * /*node*/) override {
virtual std::any visitErrorNode(ErrorNode * /*node*/) override {
return defaultResult();
}

Expand All @@ -70,8 +70,8 @@ namespace tree {
/// The base implementation returns {@code null}.
/// </summary>
/// <returns> The default value returned by visitor methods. </returns>
virtual antlrcpp::Any defaultResult() {
return nullptr; // support isNotNull
virtual std::any defaultResult() {
return std::any();
}

/// <summary>
Expand All @@ -92,7 +92,7 @@ namespace tree {
/// a child node.
/// </param>
/// <returns> The updated aggregate result. </returns>
virtual antlrcpp::Any aggregateResult(antlrcpp::Any /*aggregate*/, const antlrcpp::Any &nextResult) {
virtual std::any aggregateResult(std::any /*aggregate*/, const std::any &nextResult) {
return nextResult;
}

Expand All @@ -119,7 +119,7 @@ namespace tree {
/// <returns> {@code true} to continue visiting children. Otherwise return
/// {@code false} to stop visiting children and immediately return the
/// current aggregate result from <seealso cref="#visitChildren"/>. </returns>
virtual bool shouldVisitNextChild(ParseTree * /*node*/, const antlrcpp::Any &/*currentResult*/) {
virtual bool shouldVisitNextChild(ParseTree * /*node*/, const std::any &/*currentResult*/) {
return true;
}

Expand Down
2 changes: 1 addition & 1 deletion runtime/Cpp/runtime/src/tree/ErrorNodeImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ ErrorNodeImpl::ErrorNodeImpl(Token *token) : TerminalNodeImpl(token) {
ErrorNodeImpl::~ErrorNodeImpl() {
}

antlrcpp::Any ErrorNodeImpl::accept(ParseTreeVisitor *visitor) {
std::any ErrorNodeImpl::accept(ParseTreeVisitor *visitor) {
return visitor->visitErrorNode(this);
}
2 changes: 1 addition & 1 deletion runtime/Cpp/runtime/src/tree/ErrorNodeImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ namespace tree {
ErrorNodeImpl(Token *token);
~ErrorNodeImpl() override;

virtual antlrcpp::Any accept(ParseTreeVisitor *visitor) override;
virtual std::any accept(ParseTreeVisitor *visitor) override;
};

} // namespace tree
Expand Down
2 changes: 1 addition & 1 deletion runtime/Cpp/runtime/src/tree/ParseTree.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ namespace tree {

/// The <seealso cref="ParseTreeVisitor"/> needs a double dispatch method.
// ml: This has been changed to use Any instead of a template parameter, to avoid the need of a virtual template function.
virtual antlrcpp::Any accept(ParseTreeVisitor *visitor) = 0;
virtual std::any accept(ParseTreeVisitor *visitor) = 0;

/// Return the combined text of all leaf nodes. Does not get any
/// off-channel tokens (if any) so won't return whitespace and
Expand Down
8 changes: 4 additions & 4 deletions runtime/Cpp/runtime/src/tree/ParseTreeVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,29 +27,29 @@ namespace tree {
/// </summary>
/// <param name="tree"> The <seealso cref="ParseTree"/> to visit. </param>
/// <returns> The result of visiting the parse tree. </returns>
virtual antlrcpp::Any visit(ParseTree *tree) = 0;
virtual std::any visit(ParseTree *tree) = 0;

/// <summary>
/// Visit the children of a node, and return a user-defined result of the
/// operation.
/// </summary>
/// <param name="node"> The <seealso cref="ParseTree"/> whose children should be visited. </param>
/// <returns> The result of visiting the children of the node. </returns>
virtual antlrcpp::Any visitChildren(ParseTree *node) = 0;
virtual std::any visitChildren(ParseTree *node) = 0;

/// <summary>
/// Visit a terminal node, and return a user-defined result of the operation.
/// </summary>
/// <param name="node"> The <seealso cref="TerminalNode"/> to visit. </param>
/// <returns> The result of visiting the node. </returns>
virtual antlrcpp::Any visitTerminal(TerminalNode *node) = 0;
virtual std::any visitTerminal(TerminalNode *node) = 0;

/// <summary>
/// Visit an error node, and return a user-defined result of the operation.
/// </summary>
/// <param name="node"> The <seealso cref="ErrorNode"/> to visit. </param>
/// <returns> The result of visiting the node. </returns>
virtual antlrcpp::Any visitErrorNode(ErrorNode *node) = 0;
virtual std::any visitErrorNode(ErrorNode *node) = 0;

};

Expand Down
2 changes: 1 addition & 1 deletion runtime/Cpp/runtime/src/tree/TerminalNodeImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ misc::Interval TerminalNodeImpl::getSourceInterval() {
return misc::Interval(tokenIndex, tokenIndex);
}

antlrcpp::Any TerminalNodeImpl::accept(ParseTreeVisitor *visitor) {
std::any TerminalNodeImpl::accept(ParseTreeVisitor *visitor) {
return visitor->visitTerminal(this);
}

Expand Down
2 changes: 1 addition & 1 deletion runtime/Cpp/runtime/src/tree/TerminalNodeImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ namespace tree {
virtual void setParent(RuleContext *parent) override;
virtual misc::Interval getSourceInterval() override;

virtual antlrcpp::Any accept(ParseTreeVisitor *visitor) override;
virtual std::any accept(ParseTreeVisitor *visitor) override;

virtual std::string getText() override;
virtual std::string toStringTree(Parser *parser, bool pretty = false) override;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1052,11 +1052,11 @@ void <parser.name>::<struct.name>::<if (method.isEnter)>enter<else>exit<endif>Ru

VisitorDispatchMethodHeader(method) ::= <<

virtual antlrcpp::Any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
>>
VisitorDispatchMethod(method) ::= <<

antlrcpp::Any <parser.name>::<struct.name>::accept(tree::ParseTreeVisitor *visitor) {
std::any <parser.name>::<struct.name>::accept(tree::ParseTreeVisitor *visitor) {
if (auto parserVisitor = dynamic_cast\<<parser.grammarName>Visitor*>(visitor))
return parserVisitor->visit<struct.derivedFromName; format="cap">(this);
else
Expand Down
Loading

0 comments on commit 557620d

Please sign in to comment.