diff --git a/libdevcore/Visitor.h b/libdevcore/Visitor.h new file mode 100644 index 000000000..4030c928e --- /dev/null +++ b/libdevcore/Visitor.h @@ -0,0 +1,128 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +/** + * Visitor templates. + */ + +#pragma once + +#include +#include + +namespace dev +{ + +/// Generic visitor used as follows: +/// boost::apply_visitor(GenericVisitor( +/// [](Class1& _c) { _c.f(); }, +/// [](Class2& _c) { _c.g(); } +/// ), variant); +/// This one does not have a fallback and will fail at +/// compile-time if you do not specify all variants. + +template +struct GenericVisitor{}; + +template +struct GenericVisitor: public GenericVisitor +{ + using GenericVisitor::operator (); + explicit GenericVisitor( + std::function _visitor, + std::function... _otherVisitors + ): + GenericVisitor(std::move(_otherVisitors)...), + m_visitor(std::move(_visitor)) + {} + + void operator()(Visitable& _v) const { m_visitor(_v); } + + std::function m_visitor; +}; +template <> +struct GenericVisitor<>: public boost::static_visitor<> { + void operator()() const {} +}; + +/// Generic visitor with fallback: +/// boost::apply_visitor(GenericFallbackVisitor( +/// [](Class1& _c) { _c.f(); }, +/// [](Class2& _c) { _c.g(); } +/// ), variant); +/// This one DOES have a fallback and will NOT fail at +/// compile-time if you do not specify all variants. + +template +struct GenericFallbackVisitor{}; + +template +struct GenericFallbackVisitor: public GenericFallbackVisitor +{ + explicit GenericFallbackVisitor( + std::function _visitor, + std::function... _otherVisitors + ): + GenericFallbackVisitor(std::move(_otherVisitors)...), + m_visitor(std::move(_visitor)) + {} + + using GenericFallbackVisitor::operator (); + void operator()(Visitable& _v) const { m_visitor(_v); } + + std::function m_visitor; +}; +template <> +struct GenericFallbackVisitor<>: public boost::static_visitor<> { + template + void operator()(T&) const { } +}; + +/// Generic visitor with fallback that can return a value: +/// boost::apply_visitor(GenericFallbackReturnsVisitor( +/// [](Class1& _c) { return _c.f(); }, +/// [](Class2& _c) { return _c.g(); } +/// ), variant); +/// This one DOES have a fallback and will NOT fail at +/// compile-time if you do not specify all variants. +/// The fallback {}-constructs the return value. + +template +struct GenericFallbackReturnsVisitor{}; + +template +struct GenericFallbackReturnsVisitor: public GenericFallbackReturnsVisitor +{ + explicit GenericFallbackReturnsVisitor( + std::function _visitor, + std::function... _otherVisitors + ): + GenericFallbackReturnsVisitor(std::move(_otherVisitors)...), + m_visitor(std::move(_visitor)) + {} + + using GenericFallbackReturnsVisitor::operator (); + R operator()(Visitable& _v) const { return m_visitor(_v); } + + std::function m_visitor; +}; +template +struct GenericFallbackReturnsVisitor: public boost::static_visitor { + template + R operator()(T&) const { return {}; } +}; + +} diff --git a/libsolidity/inlineasm/AsmScope.h b/libsolidity/inlineasm/AsmScope.h index c8c63f8fa..fc674e710 100644 --- a/libsolidity/inlineasm/AsmScope.h +++ b/libsolidity/inlineasm/AsmScope.h @@ -22,6 +22,8 @@ #include +#include + #include #include @@ -35,31 +37,6 @@ namespace solidity namespace assembly { -template -struct GenericVisitor{}; - -template -struct GenericVisitor: public GenericVisitor -{ - using GenericVisitor::operator (); - explicit GenericVisitor( - std::function _visitor, - std::function... _otherVisitors - ): - GenericVisitor(_otherVisitors...), - m_visitor(_visitor) - {} - - void operator()(Visitable& _v) const { m_visitor(_v); } - - std::function m_visitor; -}; -template <> -struct GenericVisitor<>: public boost::static_visitor<> { - void operator()() const {} -}; - - struct Scope { using YulType = std::string;