Skip to content

Commit

Permalink
-replace getInterface with dynamic_cast based as method
Browse files Browse the repository at this point in the history
  • Loading branch information
kamchatka-volcano committed Feb 13, 2025
1 parent 4e80f8d commit bd3ac66
Show file tree
Hide file tree
Showing 20 changed files with 62 additions and 181 deletions.
4 changes: 3 additions & 1 deletion src/attribute_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "errors.h"
#include "streamreader.h"
#include <gsl/assert>
#include <gsl/narrow>

namespace htcpp {

Expand All @@ -23,7 +24,8 @@ std::string_view AttributeNode::value() const

void AttributeNode::load(StreamReader& stream)
{
Expects(stream.read(name_.size()) == name_);
Expects(stream.read(gsl::narrow_cast<int>(std::ssize(name_))) == name_);

stream.skipWhitespace();
if (stream.peek() != "=")
throw TemplateError{stream.position(), "Attribute '" + name_ + "'s value is missing"};
Expand Down
4 changes: 2 additions & 2 deletions src/attribute_node.h
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
#pragma once
#include "iattribute.h"
#include "idocumentnode.h"
#include <string>
#include <string_view>

namespace htcpp {

class StreamReader;

class AttributeNode : public IDocumentNode,
public IAttribute {
DOCUMENT_NODE_INTERFACE_ACCESS(IAttribute)

public:
explicit AttributeNode(std::string name, StreamReader& stream);
std::string_view name() const override;
Expand Down
3 changes: 2 additions & 1 deletion src/codenode.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#include "codenode.h"
#include "streamreader.h"
#include "errors.h"
#include "streamreader.h"
#include "utils.h"
#include <gsl/assert>
#include <utility>

namespace htcpp{
Expand Down
5 changes: 0 additions & 5 deletions src/codenode.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#pragma once
#include "document_node_interface_access.h"
#include "idocumentnode.h"
#include "idocumentnoderenderer.h"
#include "nodeextension.h"
Expand Down Expand Up @@ -27,7 +26,6 @@ class CodeNode {

class ExpressionNode : public IDocumentNode,
public IDocumentNodeRenderer {
DOCUMENT_NODE_INTERFACE_ACCESS(IDocumentNodeRenderer)
public:
explicit ExpressionNode(StreamReader& stream);
std::string renderingCode() const override;
Expand All @@ -38,8 +36,6 @@ class ExpressionNode : public IDocumentNode,

class StatementNode : public IDocumentNode,
public IDocumentNodeRenderer {
DOCUMENT_NODE_INTERFACE_ACCESS(IDocumentNodeRenderer)

public:
explicit StatementNode(StreamReader& stream);
std::string renderingCode() const override;
Expand All @@ -50,7 +46,6 @@ class StatementNode : public IDocumentNode,

class GlobalStatementNode : public IDocumentNode,
public IDocumentNodeRenderer {
DOCUMENT_NODE_INTERFACE_ACCESS(IDocumentNodeRenderer)
public:
explicit GlobalStatementNode(StreamReader& stream);
std::string renderingCode() const override;
Expand Down
3 changes: 0 additions & 3 deletions src/control_flow_statement_node.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#pragma once
#include "document_node_interface_access.h"
#include "idocumentnode.h"
#include "idocumentnoderenderer.h"
#include "nodeextension.h"
Expand All @@ -15,8 +14,6 @@ enum class ControlFlowStatementNodeType {

class ControlFlowStatementNode : public IDocumentNode,
public IDocumentNodeRenderer {
DOCUMENT_NODE_INTERFACE_ACCESS(IDocumentNodeRenderer)

public:
ControlFlowStatementNode(ControlFlowStatementNodeType, NodeExtension nodeExtension);
std::string renderingCode() const override;
Expand Down
26 changes: 0 additions & 26 deletions src/document_node_interface_access.h

This file was deleted.

7 changes: 4 additions & 3 deletions src/iconvertible_to_procedure.h
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
#pragma once
#include <sfun/interface.h>
#include <optional>
#include <string_view>

namespace htcpp{
namespace htcpp {

class IConvertibleToProcedure : private sfun::interface<IConvertibleToProcedure> {
public:
virtual std::string_view procedureName() const = 0;
virtual std::optional<std::string_view> procedureName() const = 0;
};

}
} //namespace htcpp
37 changes: 8 additions & 29 deletions src/idocumentnode.h
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
#pragma once
#include "document_node_interface_access.h"
#include <sfun/interface.h>
#include <sfun/optional_ref.h>
#include <gsl/assert>
#include <string>
#include <typeinfo>
#include <memory>
#include <vector>

namespace htcpp {
class INodeCollection;
Expand All @@ -22,39 +16,24 @@ class IDocumentNode : private sfun::interface<IDocumentNode>
{
public:
template<typename TInterface>
auto getInterface() const
sfun::optional_ref<const TInterface> as() const
{
return (this->*InterfaceGetterMapping<TInterface>::getterPtr())();
auto obj = dynamic_cast<const TInterface*>(this);
return obj ? sfun::optional_ref<const TInterface>{*obj} : sfun::optional_ref<const TInterface>{};
}

template<typename TInterface>
auto getInterface()
sfun::optional_ref<TInterface> as()
{
return (this->*InterfaceGetterMapping<TInterface>::getterPtr())();
auto obj = dynamic_cast<TInterface*>(this);
return obj ? sfun::optional_ref<TInterface>{*obj} : sfun::optional_ref<TInterface>{};
}

template<typename T>
bool is()
bool is() const
{
return typeid(*this) == typeid(T);
return as<T>().has_value();
}

private:
DOCUMENT_NODE_ADD_INTERFACE_GETTER(INodeCollection);
DOCUMENT_NODE_ADD_INTERFACE_GETTER(IDocumentNodeRenderer);
DOCUMENT_NODE_ADD_INTERFACE_GETTER(IRenderedAsStringPart);
DOCUMENT_NODE_ADD_INTERFACE_GETTER(IConvertibleToProcedure);
DOCUMENT_NODE_ADD_INTERFACE_GETTER(IAttribute);

template<typename TInterface>
friend struct InterfaceGetterMapping;
};

DOCUMENT_NODE_REGISTER_INTERFACE(INodeCollection);
DOCUMENT_NODE_REGISTER_INTERFACE(IDocumentNodeRenderer);
DOCUMENT_NODE_REGISTER_INTERFACE(IRenderedAsStringPart);
DOCUMENT_NODE_REGISTER_INTERFACE(IConvertibleToProcedure);
DOCUMENT_NODE_REGISTER_INTERFACE(IAttribute);


} // namespace htcpp
8 changes: 4 additions & 4 deletions src/node_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ std::vector<std::unique_ptr<IDocumentNode>> flattenNodes(std::vector<std::unique
{
auto flattenNodes = std::vector<std::unique_ptr<IDocumentNode>>{};
for (auto& node : nodes) {
if (const auto nodeCollection = node->template getInterface<INodeCollection>())
if (const auto nodeCollection = node->template as<INodeCollection>())
std::ranges::move(nodeCollection->flatten(), std::back_inserter(flattenNodes));
else
flattenNodes.emplace_back(std::move(node));
Expand All @@ -20,9 +20,9 @@ std::vector<std::unique_ptr<IDocumentNode>> optimizeNodes(std::vector<std::uniqu
{
auto processedNodes = std::vector<std::unique_ptr<IDocumentNode>>{};
for (auto& node : nodes) {
if (auto text = node->getInterface<IRenderedAsStringPart>()) {
if (!processedNodes.empty() && processedNodes.back()->getInterface<IRenderedAsStringPart>()) {
auto prevText = processedNodes.back()->getInterface<IRenderedAsStringPart>()->content();
if (auto text = node->as<IRenderedAsStringPart>()) {
if (!processedNodes.empty() && processedNodes.back()->as<IRenderedAsStringPart>()) {
auto prevText = processedNodes.back()->as<IRenderedAsStringPart>()->content();
processedNodes.back() = std::make_unique<TextNode>(prevText + text->content());
}
else
Expand Down
5 changes: 3 additions & 2 deletions src/procedurenode.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
#include "procedurenode.h"
#include "errors.h"
#include "idocumentnoderenderer.h"
#include "node_utils.h"
#include "nodereader.h"
#include "streamreader.h"
#include "utils.h"
#include "node_utils.h"
#include <gsl/assert>

namespace htcpp{

Expand Down Expand Up @@ -58,7 +59,7 @@ std::string ProcedureNode::renderingCode() const
{
auto result = std::string{};
for (auto& node : contentNodes_)
result += node->getInterface<IDocumentNodeRenderer>()->renderingCode();
result += node->as<IDocumentNodeRenderer>()->renderingCode();
return result;
}

Expand Down
3 changes: 0 additions & 3 deletions src/procedurenode.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#pragma once
#include "document_node_interface_access.h"
#include "idocumentnode.h"
#include "idocumentnoderenderer.h"
#include <memory>
Expand All @@ -11,8 +10,6 @@ class StreamReader;

class ProcedureNode : public IDocumentNode,
public IDocumentNodeRenderer {
DOCUMENT_NODE_INTERFACE_ACCESS(IDocumentNodeRenderer)

public:
ProcedureNode(std::string procedureName, StreamReader& stream);
ProcedureNode(std::string procedureName, std::unique_ptr<IDocumentNode> contentNode);
Expand Down
44 changes: 10 additions & 34 deletions src/sectionnode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,10 @@ std::vector<std::unique_ptr<IDocumentNode>> SectionNode::flatten()
result.emplace_back(
std::make_unique<ControlFlowStatementNode>(ControlFlowStatementNodeType::Open, extension_.value()));
for (auto& node : contentNodes_) {
if (node->getInterface<IAttribute>().has_value())
if (node->as<IAttribute>().has_value())
continue;

if (auto nodeCollection = node->getInterface<INodeCollection>())
if (auto nodeCollection = node->as<INodeCollection>())
std::ranges::move(nodeCollection->flatten(), std::back_inserter(result));
else
result.emplace_back(std::move(node));
Expand All @@ -78,46 +78,22 @@ std::vector<std::unique_ptr<IDocumentNode>> SectionNode::flatten()
return result;
}

template<typename T>
sfun::optional_ref<T> getIConvertibleToProcedure(auto selfPtr)
{
if (std::ranges::any_of(
selfPtr->contentNodes_,
[](const auto& node)
{
return node->template getInterface<IAttribute>().has_value();
}))
return selfPtr;

return std::nullopt;
}

sfun::optional_ref<const IConvertibleToProcedure> SectionNode::getIConvertibleToProcedure() const
{
return getIConvertibleToProcedure<const IConvertibleToProcedure>(this);
}

sfun::optional_ref<IConvertibleToProcedure> SectionNode::getIConvertibleToProcedure()
{
return getIConvertibleToProcedure<IConvertibleToProcedure>(this);
}

std::string_view SectionNode::procedureName() const
std::optional<std::string_view> SectionNode::procedureName() const
{
auto idAttribute = std::ranges::find_if(
contentNodes_,
[](const auto& node)
{
auto attribute = node->template getInterface<IAttribute>();
if (!attribute.has_value())
return false;
return attribute->name() == "htcpp-id";
});
auto attribute = node->template as<IAttribute>();
if (!attribute.has_value())
return false;
return attribute->name() == "htcpp-id";
});

if (idAttribute == contentNodes_.end())
return {};
return std::nullopt;

return idAttribute->get()->template getInterface<IAttribute>()->value();
return idAttribute->get()->template as<IAttribute>()->value();
}

} //namespace htcpp
10 changes: 1 addition & 9 deletions src/sectionnode.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#pragma once
#include "document_node_interface_access.h"
#include "idocumentnode.h"
#include "inodecollection.h"
#include "iconvertible_to_procedure.h"
Expand All @@ -13,21 +12,14 @@ namespace htcpp{
class SectionNode : public IDocumentNode,
public INodeCollection,
public IConvertibleToProcedure {
DOCUMENT_NODE_INTERFACE_ACCESS(INodeCollection)

public:
explicit SectionNode(StreamReader& stream);
std::vector<std::unique_ptr<IDocumentNode>>& content() override;
std::vector<std::unique_ptr<IDocumentNode>> flatten() override;
std::string_view procedureName() const override;

sfun::optional_ref<const IConvertibleToProcedure> getIConvertibleToProcedure() const override;
sfun::optional_ref<IConvertibleToProcedure> getIConvertibleToProcedure() override;
std::optional<std::string_view> procedureName() const override;

private:
void load(StreamReader& stream);
template<typename T>
friend sfun::optional_ref<T> getIConvertibleToProcedure(auto selfPtr);

private:
std::vector<std::unique_ptr<IDocumentNode>> contentNodes_;
Expand Down
Loading

0 comments on commit bd3ac66

Please sign in to comment.