Skip to content

Commit

Permalink
Add a macro which generates a SFINAE template for checking NUClear wo…
Browse files Browse the repository at this point in the history
…rds (#155)

All of the NUClear DSL words follow a similar pattern for working out if
a DSL word exists.
This makes a macro which can generate this pattern rather than having
almost identical lines all through individual files.
  • Loading branch information
TrentHouliston authored Oct 26, 2024
1 parent 4a83418 commit 12fab9a
Show file tree
Hide file tree
Showing 17 changed files with 92 additions and 475 deletions.
5 changes: 4 additions & 1 deletion src/dsl/fusion/BindFusion.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,15 @@
#include "../../util/FunctionFusion.hpp"
#include "../operation/DSLProxy.hpp"
#include "FindWords.hpp"
#include "has_bind.hpp"
#include "has_nuclear_dsl_method.hpp"

namespace NUClear {
namespace dsl {
namespace fusion {

/// Make a SFINAE type to check if a word has a run_inline method
HAS_NUCLEAR_DSL_METHOD(bind);

/**
* This is our Function Fusion wrapper class that allows it to call bind functions.
*
Expand Down
5 changes: 4 additions & 1 deletion src/dsl/fusion/GetFusion.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,15 @@
#include "../../util/tuplify.hpp"
#include "../operation/DSLProxy.hpp"
#include "FindWords.hpp"
#include "has_get.hpp"
#include "has_nuclear_dsl_method.hpp"

namespace NUClear {
namespace dsl {
namespace fusion {

/// Make a SFINAE type to check if a word has a get method
HAS_NUCLEAR_DSL_METHOD(get);

/**
* This is our Function Fusion wrapper class that allows it to call get functions.
*
Expand Down
5 changes: 4 additions & 1 deletion src/dsl/fusion/GroupFusion.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,15 @@
#include "../../threading/Reaction.hpp"
#include "../operation/DSLProxy.hpp"
#include "FindWords.hpp"
#include "has_group.hpp"
#include "has_nuclear_dsl_method.hpp"

namespace NUClear {
namespace dsl {
namespace fusion {

/// Make a SFINAE type to check if a word has a group method
HAS_NUCLEAR_DSL_METHOD(group);

// Default case where there are no group words
template <typename Words>
struct GroupFuser {};
Expand Down
5 changes: 4 additions & 1 deletion src/dsl/fusion/InlineFusion.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,15 @@
#include "../../util/Inline.hpp"
#include "../operation/DSLProxy.hpp"
#include "FindWords.hpp"
#include "has_run_inline.hpp"
#include "has_nuclear_dsl_method.hpp"

namespace NUClear {
namespace dsl {
namespace fusion {

/// Make a SFINAE type to check if a word has a run_inline method
HAS_NUCLEAR_DSL_METHOD(run_inline);

// Default case where there are no Inline words
template <typename Words>
struct InlineFuser {};
Expand Down
5 changes: 4 additions & 1 deletion src/dsl/fusion/PoolFusion.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,15 @@
#include "../../threading/ReactionTask.hpp"
#include "../operation/DSLProxy.hpp"
#include "FindWords.hpp"
#include "has_pool.hpp"
#include "has_nuclear_dsl_method.hpp"

namespace NUClear {
namespace dsl {
namespace fusion {

/// Make a SFINAE type to check if a word has a pool method
HAS_NUCLEAR_DSL_METHOD(pool);

// Default case where there are no pool words
template <typename Words>
struct PoolFuser {};
Expand Down
5 changes: 4 additions & 1 deletion src/dsl/fusion/PostconditionFusion.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,15 @@
#include "../../threading/ReactionTask.hpp"
#include "../operation/DSLProxy.hpp"
#include "FindWords.hpp"
#include "has_postcondition.hpp"
#include "has_nuclear_dsl_method.hpp"

namespace NUClear {
namespace dsl {
namespace fusion {

/// Make a SFINAE type to check if a word has a postcondition method
HAS_NUCLEAR_DSL_METHOD(postcondition);

// Default case where there are no postcondition words
template <typename Words>
struct PostconditionFuser {};
Expand Down
5 changes: 4 additions & 1 deletion src/dsl/fusion/PreconditionFusion.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,15 @@
#include "../../threading/ReactionTask.hpp"
#include "../operation/DSLProxy.hpp"
#include "FindWords.hpp"
#include "has_precondition.hpp"
#include "has_nuclear_dsl_method.hpp"

namespace NUClear {
namespace dsl {
namespace fusion {

/// Make a SFINAE type to check if a word has a precondition method
HAS_NUCLEAR_DSL_METHOD(precondition);

// Default case where there are no precondition words
template <typename Words>
struct PreconditionFuser {};
Expand Down
5 changes: 4 additions & 1 deletion src/dsl/fusion/PriorityFusion.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,15 @@
#include "../../threading/ReactionTask.hpp"
#include "../operation/DSLProxy.hpp"
#include "FindWords.hpp"
#include "has_priority.hpp"
#include "has_nuclear_dsl_method.hpp"

namespace NUClear {
namespace dsl {
namespace fusion {

/// Make a SFINAE type to check if a word has a priority method
HAS_NUCLEAR_DSL_METHOD(priority);

// Default case where there are no priority words
template <typename Words>
struct PriorityFuser {};
Expand Down
61 changes: 0 additions & 61 deletions src/dsl/fusion/has_bind.hpp

This file was deleted.

58 changes: 0 additions & 58 deletions src/dsl/fusion/has_get.hpp

This file was deleted.

58 changes: 0 additions & 58 deletions src/dsl/fusion/has_group.hpp

This file was deleted.

60 changes: 60 additions & 0 deletions src/dsl/fusion/has_nuclear_dsl_method.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* MIT License
*
* Copyright (c) 2024 NUClear Contributors
*
* This file is part of the NUClear codebase.
* See https://github.com/Fastcode/NUClear for further info.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
* documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#ifndef NUCLEAR_DSL_FUSION_FUSION_HAS_NUCLEAR_DSL_METHOD_HPP
#define NUCLEAR_DSL_FUSION_FUSION_HAS_NUCLEAR_DSL_METHOD_HPP

#include "NoOp.hpp"

/**
* This macro to create an SFINAE type to check for the existence of a NUClear DSL method in a given class.
*
* The macro generates a template struct that can be used to determine if a class contains a specific method.
*
* The macro works by attempting to instantiate a function pointer to the method in question.
* If the method exists, the instantiation will succeed and the struct will inherit from
* `std::true_type`. Otherwise, it will inherit from `std::false_type`.
*
* @note This macro assumes that the method being checked for is a template method that can be instantiated with
* `ParsedNoOp`.
*/
// If you can find a way to do SFINAE in a constexpr for a variable function name let me know
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define HAS_NUCLEAR_DSL_METHOD(Method) \
template <typename Word> \
struct has_##Method { \
private: \
template <typename R, typename... A> \
static auto test_func(R (*)(A...)) -> std::true_type; \
static auto test_func(...) -> std::false_type; \
\
/* Parenthesis would literally break this code*/ \
template <typename U> /* NOLINTNEXTLINE(bugprone-macro-parentheses) */ \
static auto test(int) -> decltype(test_func(&U::template Method<ParsedNoOp>)); \
template <typename> \
static auto test(...) -> std::false_type; \
\
public: \
static constexpr bool value = decltype(test<Word>(0))::value; \
}

#endif // NUCLEAR_DSL_FUSION_FUSION_HAS_NUCLEAR_DSL_METHOD_HPP
Loading

0 comments on commit 12fab9a

Please sign in to comment.