Skip to content

Commit

Permalink
Allow custom types to specify a dereference_type for operator[]
Browse files Browse the repository at this point in the history
  • Loading branch information
AjayBrahmakshatriya committed Dec 4, 2024
1 parent c980a84 commit 026c015
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 7 deletions.
5 changes: 0 additions & 5 deletions include/builder/block_type_extractor.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,6 @@ struct custom_type_base;



template <typename T>
struct check_valid_type {
typedef void type;
};

extern int type_naming_counter;

template <typename T, typename V=void>
Expand Down
32 changes: 30 additions & 2 deletions include/builder/dyn_var.h
Original file line number Diff line number Diff line change
Expand Up @@ -344,10 +344,36 @@ struct dyn_var_parent_selector<T,
>::type>
: public member_initializer_begin<T>, public std::remove_reference<T>::type, public member_initializer_end {};


template <typename T>
class dyn_var_mimic;


// These helper classes provide implementation of the operator[]
// The return type is selected based on whether the T has a member called dereference_type defined
// if it is defined, the return is builder::cast'd to a dyn_var (mimic) of that type (just like *)
// otherwise a regular builder return implementation is provided
// This allows implementation of vector<> types with appropriate return types
template <typename T, typename V>
struct dyn_var_deref_provider {
builder operator[] (const builder& b) {
return static_cast<dyn_var<T>*>(this)->dyn_var_impl<T>::operator[](b);
}
};

template <typename T>
struct dyn_var_deref_provider<T, typename check_valid_type<typename T::dereference_type>::type> {
dyn_var_mimic<typename T::dereference_type> operator[] (const builder& b) {
return (cast)(static_cast<dyn_var<T>*>(this)->dyn_var_impl<T>::operator[](b));
}
};



// Actual dyn_var implementation
// Split design to allow for easily extending types with specialization
template <typename T>
class dyn_var : public dyn_var_impl<T>, public dyn_var_parent_selector<T, void> {
class dyn_var : public dyn_var_impl<T>, public dyn_var_parent_selector<T, void>, public dyn_var_deref_provider<T, void> {
public:
typedef dyn_var_impl<T> super;

Expand All @@ -366,10 +392,12 @@ class dyn_var : public dyn_var_impl<T>, public dyn_var_parent_selector<T, void>
builder operator=(const dyn_var<T> &t) {
return *this = (builder)t;
}

using dyn_var_deref_provider<T, void>::operator[];
};

// dyn var specialization for pointer types to return the appropriate types on [], * and ->

// dyn var specialization for pointer types to return the appropriate types on [], * and ->
template <typename T>
class dyn_var_mimic: public dyn_var<T> {
// Behaves exactly like a dyn_var for most purposes
Expand Down
6 changes: 6 additions & 0 deletions include/builder/forward_declarations.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ struct with_name {
with_name(const std::string &n, bool wd = false) : name(n), with_decl(wd) {}
};

template <typename T>
struct check_valid_type {
typedef void type;
};



} // namespace builder
#endif
29 changes: 29 additions & 0 deletions samples/outputs.var_names/sample59
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
FUNC_DECL
SCALAR_TYPE (VOID)
STMT_BLOCK
DECL_STMT
NAMED_TYPE (std::vector)
NAMED_TYPE (std::vector)
SCALAR_TYPE (INT)
VAR (x_0)
NO_INITIALIZATION
EXPR_STMT
FUNCTION_CALL_EXPR
MEMBER_ACCESS_EXPR (resize)
VAR_EXPR
VAR (x_0)
INT_CONST (2)
EXPR_STMT
FUNCTION_CALL_EXPR
MEMBER_ACCESS_EXPR (resize)
SQ_BKT_EXPR
VAR_EXPR
VAR (x_0)
INT_CONST (1)
INT_CONST (1)
void bar (void) {
std::vector<std::vector<int>> x_0;
x_0.resize(2);
(x_0[1]).resize(1);
}

29 changes: 29 additions & 0 deletions samples/outputs/sample59
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
FUNC_DECL
SCALAR_TYPE (VOID)
STMT_BLOCK
DECL_STMT
NAMED_TYPE (std::vector)
NAMED_TYPE (std::vector)
SCALAR_TYPE (INT)
VAR (var0)
NO_INITIALIZATION
EXPR_STMT
FUNCTION_CALL_EXPR
MEMBER_ACCESS_EXPR (resize)
VAR_EXPR
VAR (var0)
INT_CONST (2)
EXPR_STMT
FUNCTION_CALL_EXPR
MEMBER_ACCESS_EXPR (resize)
SQ_BKT_EXPR
VAR_EXPR
VAR (var0)
INT_CONST (1)
INT_CONST (1)
void bar (void) {
std::vector<std::vector<int>> var0;
var0.resize(2);
(var0[1]).resize(1);
}

31 changes: 31 additions & 0 deletions samples/sample59.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include "blocks/c_code_generator.h"
#include "builder/builder.h"
#include "builder/builder_context.h"
#include "builder/dyn_var.h"
#include "builder/static_var.h"
#include "builder/lib/utils.h"
#include <iostream>
using builder::dyn_var;
using builder::static_var;


template <typename T>
struct vector: public builder::custom_type<T> {
static constexpr const char* type_name = "std::vector";
typedef T dereference_type;
dyn_var<void(int)> resize = builder::with_name("resize");
};

static void bar(void) {
dyn_var<vector<vector<int>>> x;
x.resize(2);
x[1].resize(1);
}

int main(int argc, char *argv[]) {
builder::builder_context context;
auto ast = context.extract_function_ast(bar, "bar");
ast->dump(std::cout, 0);
block::c_code_generator::generate_code(ast, std::cout, 0);
return 0;
}

0 comments on commit 026c015

Please sign in to comment.