Skip to content

Commit d7852a3

Browse files
Merge pull request #86 from AjayBrahmakshatriya/master
Allow custom types to specify a dereference_type for operator[]
2 parents c980a84 + 026c015 commit d7852a3

File tree

6 files changed

+125
-7
lines changed

6 files changed

+125
-7
lines changed

include/builder/block_type_extractor.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,6 @@ struct custom_type_base;
1010

1111

1212

13-
template <typename T>
14-
struct check_valid_type {
15-
typedef void type;
16-
};
17-
1813
extern int type_naming_counter;
1914

2015
template <typename T, typename V=void>

include/builder/dyn_var.h

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -344,10 +344,36 @@ struct dyn_var_parent_selector<T,
344344
>::type>
345345
: public member_initializer_begin<T>, public std::remove_reference<T>::type, public member_initializer_end {};
346346

347+
348+
template <typename T>
349+
class dyn_var_mimic;
350+
351+
352+
// These helper classes provide implementation of the operator[]
353+
// The return type is selected based on whether the T has a member called dereference_type defined
354+
// if it is defined, the return is builder::cast'd to a dyn_var (mimic) of that type (just like *)
355+
// otherwise a regular builder return implementation is provided
356+
// This allows implementation of vector<> types with appropriate return types
357+
template <typename T, typename V>
358+
struct dyn_var_deref_provider {
359+
builder operator[] (const builder& b) {
360+
return static_cast<dyn_var<T>*>(this)->dyn_var_impl<T>::operator[](b);
361+
}
362+
};
363+
364+
template <typename T>
365+
struct dyn_var_deref_provider<T, typename check_valid_type<typename T::dereference_type>::type> {
366+
dyn_var_mimic<typename T::dereference_type> operator[] (const builder& b) {
367+
return (cast)(static_cast<dyn_var<T>*>(this)->dyn_var_impl<T>::operator[](b));
368+
}
369+
};
370+
371+
372+
347373
// Actual dyn_var implementation
348374
// Split design to allow for easily extending types with specialization
349375
template <typename T>
350-
class dyn_var : public dyn_var_impl<T>, public dyn_var_parent_selector<T, void> {
376+
class dyn_var : public dyn_var_impl<T>, public dyn_var_parent_selector<T, void>, public dyn_var_deref_provider<T, void> {
351377
public:
352378
typedef dyn_var_impl<T> super;
353379

@@ -366,10 +392,12 @@ class dyn_var : public dyn_var_impl<T>, public dyn_var_parent_selector<T, void>
366392
builder operator=(const dyn_var<T> &t) {
367393
return *this = (builder)t;
368394
}
395+
396+
using dyn_var_deref_provider<T, void>::operator[];
369397
};
370398

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

400+
// dyn var specialization for pointer types to return the appropriate types on [], * and ->
373401
template <typename T>
374402
class dyn_var_mimic: public dyn_var<T> {
375403
// Behaves exactly like a dyn_var for most purposes

include/builder/forward_declarations.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,12 @@ struct with_name {
6060
with_name(const std::string &n, bool wd = false) : name(n), with_decl(wd) {}
6161
};
6262

63+
template <typename T>
64+
struct check_valid_type {
65+
typedef void type;
66+
};
67+
68+
6369

6470
} // namespace builder
6571
#endif

samples/outputs.var_names/sample59

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
FUNC_DECL
2+
SCALAR_TYPE (VOID)
3+
STMT_BLOCK
4+
DECL_STMT
5+
NAMED_TYPE (std::vector)
6+
NAMED_TYPE (std::vector)
7+
SCALAR_TYPE (INT)
8+
VAR (x_0)
9+
NO_INITIALIZATION
10+
EXPR_STMT
11+
FUNCTION_CALL_EXPR
12+
MEMBER_ACCESS_EXPR (resize)
13+
VAR_EXPR
14+
VAR (x_0)
15+
INT_CONST (2)
16+
EXPR_STMT
17+
FUNCTION_CALL_EXPR
18+
MEMBER_ACCESS_EXPR (resize)
19+
SQ_BKT_EXPR
20+
VAR_EXPR
21+
VAR (x_0)
22+
INT_CONST (1)
23+
INT_CONST (1)
24+
void bar (void) {
25+
std::vector<std::vector<int>> x_0;
26+
x_0.resize(2);
27+
(x_0[1]).resize(1);
28+
}
29+

samples/outputs/sample59

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
FUNC_DECL
2+
SCALAR_TYPE (VOID)
3+
STMT_BLOCK
4+
DECL_STMT
5+
NAMED_TYPE (std::vector)
6+
NAMED_TYPE (std::vector)
7+
SCALAR_TYPE (INT)
8+
VAR (var0)
9+
NO_INITIALIZATION
10+
EXPR_STMT
11+
FUNCTION_CALL_EXPR
12+
MEMBER_ACCESS_EXPR (resize)
13+
VAR_EXPR
14+
VAR (var0)
15+
INT_CONST (2)
16+
EXPR_STMT
17+
FUNCTION_CALL_EXPR
18+
MEMBER_ACCESS_EXPR (resize)
19+
SQ_BKT_EXPR
20+
VAR_EXPR
21+
VAR (var0)
22+
INT_CONST (1)
23+
INT_CONST (1)
24+
void bar (void) {
25+
std::vector<std::vector<int>> var0;
26+
var0.resize(2);
27+
(var0[1]).resize(1);
28+
}
29+

samples/sample59.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#include "blocks/c_code_generator.h"
2+
#include "builder/builder.h"
3+
#include "builder/builder_context.h"
4+
#include "builder/dyn_var.h"
5+
#include "builder/static_var.h"
6+
#include "builder/lib/utils.h"
7+
#include <iostream>
8+
using builder::dyn_var;
9+
using builder::static_var;
10+
11+
12+
template <typename T>
13+
struct vector: public builder::custom_type<T> {
14+
static constexpr const char* type_name = "std::vector";
15+
typedef T dereference_type;
16+
dyn_var<void(int)> resize = builder::with_name("resize");
17+
};
18+
19+
static void bar(void) {
20+
dyn_var<vector<vector<int>>> x;
21+
x.resize(2);
22+
x[1].resize(1);
23+
}
24+
25+
int main(int argc, char *argv[]) {
26+
builder::builder_context context;
27+
auto ast = context.extract_function_ast(bar, "bar");
28+
ast->dump(std::cout, 0);
29+
block::c_code_generator::generate_code(ast, std::cout, 0);
30+
return 0;
31+
}

0 commit comments

Comments
 (0)