ENIGMA Forums
General fluff => Announcements => Topic started by: Josh @ Dreamland on January 01, 2010, 02:55:36 am
-
And a happy new decade along with that.
I just finished getting cpp_type_traits.h to parse correctly. That's an accomplishment. Along with that, however, is a regular type_traits.h, which I will be attacking next.
I don't want to give a release date after what happened last time, but I realize now that release dates are the only reason releases happen, so I guess I'm going to have to set one before the end of the month. I don't want to name the date I'm fancying now, some may be able to guess, but the rest of you can just not get your hopes up until I see what the rest of STL brings.
Anyway, a happy new year (and decade) to everyone, and quick recovery to some of my drunker friends.
...I can't stay awake much longer.
I thought this was working a minute ago, but evidently it was just something similar.
template<bool, typename>
struct __enable_if
{ };
template<typename _Tp>
struct __enable_if<true, _Tp>
{ _Tp __type; };
Honestly, it'd help to have a list of all template hacks up front. No, not just a reference on templates. A list of these goddamn hacks.
Anyway, good night.
-
Sounds good that you can finally tell us a loose release date.
And again, have a good time in dreamland.
-
"so I guess I'm going to have to set one before the end of the month." <- do you mean R4 will be released or u'll set a release date?
-
add $year $year 1
beq $year 2012 END_OF_THE_WORLD
jump NEW_YEARS_DAY
-
add $year $year 1
beq $year 2012 END_OF_THE_WORLD
jump NEW_YEARS_DAY
Hoax.
-
Also for all the newbies, I >>assume<< that when he means R4 is released it's just the ENIGMA parser itself, not 100% complete with all GM functions.
But that also means that once that's released, the gm functions will very quickly be filled in ;p
Thanks Josh you update k1ng, and Happy New Years everyone :D:D
-
kkg--
Correct. The parser will need some testing by the general userbase. I have a file of general GML to run it on, but there are so many new scenarios... It'll be best just to have a bunch of users bombard it with test code while some other C coders and I do more functions.
-
If it works on Linux i'll test the hell out of it.
-
R4 isn't just a new parser. It'll also be when Josh decides to finally merge in my R3 branch's ENIGMAsystem which is a branch of his updated R3 ENIGMAsystem
-
add $year $year 1
beq $year 2012 END_OF_THE_WORLD
jump NEW_YEARS_DAY
What horrible dialect of ASM is that, that starts variables with $ and mixes "B" and "JMP" ("JUMP"?) notations?
-
It's loosely MIPS. I actually copy pasted it from a friend. If I were to make it more accurate, I would have used "addi" instead of "add" and "j" instead of "jump"
-
Ism's code:
Increments year
Branches on equal if year is 2012
then jumps to new years day
In C:
++year;
if(year==2012) goto END_OF_THE_WORLD;
goto NEW_YEARS_DAY;
All register names(such as $t0, $s0, $0, etc. start with a $) in MIPS 32.
-
gnu99, single statement: goto*(++year==2012?&&END_OF_THE_WORLD:&&NEW_YEARS_DAY);
-
It's loosely MIPS. I actually copy pasted it from a friend. If I were to make it more accurate, I would have used "addi" instead of "add" and "j" instead of "jump"
In that case... let me rewrite it in X86 ASM, slightly more relevant :p
inc dword[year]
cmp dword[year],2012
jz END_OF_THE_WORLD
jmp NEW_YEARS_DAY
Though really, a JMP after a JZ is only excusable if you're reusing that code somewhere else or if NEW_YEARS_DAY in fact contains this code and is the start of a loop.
-
it's in another segment
-
On the topic of covering the GML functions and Rusky, I've been working on what Rusky failed at. Except to keep it a hassle for Josh, I've been implementing ds_* functions for a different engine: http://github.com/serprex/dysvk/blob/master/dss.c
-
Grammar fail. What exactly did I fail at? Doing all the ds_* functions, yes, but what I did worked.
-
TBH, I'd never touch the ds_* functions, ever. I'd just use STL, instead, or something similar.
-
Which will be possible thanks to this EVER-CLOSER-DRAWING TO COMPLETION MOTHER FUCKING PARSER.
-
exactly. but they're still good for compatibility.
-
Which will be possible thanks to this EVER-CLOSER-DRAWING TO COMPLETION MOTHER FUCKING PARSER.
You gave me a heart attack.
-
You're still not done with the parser?
-
miky:
Specialization and accessing of templates based on enumerated constants is the latest loop I've been thrown for. They've kept coming.
-
Why can't you leave C++ to gcc? You can still have helpful error messages.
-
Silly Rusky, that's not failure of grammar; it's ambiguity, something which I'm quite fond of. In this case I disambiguate it though, which I'm not prone to so much
As for Josh and C++, it's his lack of being able to settle. I shouldn't have been surprised he wasn't ready to settle and marry
-
I told you, if I'm to be in a gay marriage I at least want it to be polygamist as well.
Also, I want map<>. And stack<>. And anything else C++ has to offer. I Don't want to keep designing files to substitute for headers; I hate that job and as shown on the progress page, I'm bad at it. Serp's right though; I'm unable to settle. Which is why I keep following the loops it throws me for, under the pretense that eventually it will run out of them.
-
Why exactly don't you have map and stack without parsing the headers? Your excuse for not writing a full-blown parser is that you're just converting the syntax and that there's no point trying to beat "all those GNUs" working on GCC. But then you go and write a full-blown parser using your not-full-blown parsing system.
Basically: what is your parser doing that GCC doesn't, aside from adding semicolons and parentheses?
-
The semicolons are it. For custom structures to work, I have to know their names. Otherwise, "map a;" will be a syntax error or will at very least parse incorrectly. Oh, not to mention GCC isn't going to default all the unused parameters to variant for me, no matter how hard I cry.
-
So... is this just a template/structure parser so you can get STL definitions? That's a little better, but then again, is map<var, var> so bad? You already have var doing arrays, no? If people want to take advantage of static typing they'll probably be doing something more like map<string, var> or map<int, string> rather than map<var, var>.
-
Yes, but I wanted them to be able to say
map a;
And have it assume they meant map<variant, variant>.
This whole idea started when Luda bitched he wanted structs in EDL.
It's perfect, when you think about it. GM users have an inefficient way of having a structure (global, and instantiations of bloated-down objects), which Luda has apparently exploited in the past. This way will allow users, any who are willing to read a 150 word manual entry, to declare a structure as efficient as any other.
Also, parsing STL for members removes ambiguity.
string a;
a.length()... that won't even look like a syntax error, because length is a public member of a's type, string.
-
By the way, Josh, make sure that your handler doesn't see template<template<>> as the same thing as template<template<> >, although, I'm pretty sure that you've already handled that.
-
template<template<>>
template<template<> >
Are those actually different? Whitespace is not supposed to matter very much in C-based languages.
-
Yes, they are. Because whitespace DOES matter in C.
== is not the same as = =.
And >> is an operator(bitwise shift), so it is forbidden in templates.
That is, it WAS forbidden until C++0x came.
-
template<template<>>
template<template<> >
Are those actually different? Whitespace is not supposed to matter very much in C-based languages.
>> is considered as an operator, so they must be separate.
-
template<template<>>
template<template<> >
Are those actually different? Whitespace is not supposed to matter very much in C-based languages.
>> is considered as an operator, so they must be separate.
I see, *adds to list of reasons not to use C++*
-
It just comes from the stupid idea to use <> for templates. Because the lexer finds the biggest token it can and >> is an operator, closing two template tags in a row causes problems. Other than that, this behavior for the lexer makes perfect sense- it parses "asdfasdf = 3" as asdfasdf, = and 3, rather than a, s, d, f, a, s, d, f, = and 3.
-
It just comes from the stupid idea to use <> for templates.
Exactly.
Because the lexer finds the biggest token it can and >> is an operator, closing two template tags in a row causes problems. Other than that, this behavior for the lexer makes perfect sense- it parses "asdfasdf = 3" as asdfasdf, = and 3, rather than a, s, d, f, a, s, d, f, = and 3.
And if it did that (string into array of chars, i.e. NOTHING :p ), there'd really be no point in it.
-
It just comes from the stupid idea to use <> for templates. Because the lexer finds the biggest token it can and >> is an operator, closing two template tags in a row causes problems. Other than that, this behavior for the lexer makes perfect sense- it parses "asdfasdf = 3" as asdfasdf, = and 3, rather than a, s, d, f, a, s, d, f, = and 3.
It does not make sense to be green without chlorophyll.
-
D uses f!(1) instead of f<1> for templates.
C# and Java solve this problem making templates apply only to types, never numbers, so you won't ever write class X<3>>2>.
-
D uses f!(1) instead of f<1> for templates.
Good for D.
C# and Java solve this problem making templates apply only to types, never numbers, so you won't ever write class X<3>>2>.
Which is one of the reasons that C# and Java suck. Number templates are extremely useful in some cases.
-
Like fucking up my parser. Twice.
-
C# and Java solve this problem making templates apply only to types, never numbers, so you won't ever write class X<3>>2>.
Which is one of the reasons that C# and Java suck. Number templates are extremely useful in some cases.
Well, C# and Java don't really have templates if I'm not mistaken; they just have runtime generics, and with runtime generics it only really makes sense to have type arguments, doesn't it?
-
Yes, they are called generics in C# and Java.
Now, C# has generics on the runtime. Java doesn't even have that. Generics are a compile-time trick. They are erased from the binary. Which is the number 1 problem with Java generics.
As for C#, I don't see how numeric generics could be used but, then again, I don't see what they're for in C++ either.
-
In C++ you can make statically-allocated containers of varying sizes:
template <typename Value, int size>
class Stack {
private:
Value value[size];
public:
...
};
-
I guess, but you can still use calloc/new[], right? (I know, not compile time, not as efficient)
-
Of course, but now it adds an additional pointer instead of just being in a nice array. Which means the struct itself can likewise be in a nice array, no pointers. Less chance for segfault that way, too.
-
If you were score_under you could just set up the stack yourself and allocate dynamically-sized stuff on the stack. :P
-
In C++ you can make statically-allocated containers of varying sizes:
template <typename Value, int size>
class Stack {
private:
Value value[size];
public:
...
};
or create constant values for classes:
template<const int id> class thing
{
public: const int get_id() { return id; }
}
-
What's with the const? Template parameters take the pickiest form of const you can even imagine. That's like prefixing "long" to a Bignum.
-
What's with the const? Template parameters take the pickiest form of const you can even imagine. That's like prefixing "long" to a Bignum.
template<int id> class thing
{
public: int get_id() { return id; }
}
-
...why do you need templates for that?
-
...why do you need templates for that?
So that you can have a constant value in a certain class as a type. That class alone is useless, but you can store other things in it. That meaning, you can actually find out what class is what and perform an action based upon this depending on what the class is.
-
So basically manual RTTI and/or virtual functions?
-
So basically manual RTTI and/or virtual functions?
RTTI, yes, virtual functions... I guess, but not really.
Bad example, but:
template<bool negative> class number
{
public: uint64 value;
public: bool is_negative() { return negative; }
}
-
class Array{
public: virtual size_t getLength() = 0;
};
class StaticArray<int length> : public Array{
public:
void* arrayData[T];
virtual size_t getLength(){
return length;
}
}
I didn't bother to check if this compiles, but if this is possible, then it's a more efficient solution for static arrays with a getLength property than the ones I used in the past.
-
class Array{
public: virtual size_t getLength() = 0;
};
class StaticArray<int length> : public Array{
public:
void* arrayData[T];
virtual size_t getLength(){
return length;
}
}
I didn't bother to check if this compiles, but if this is possible, then it's a more efficient solution for static arrays with a getLength property than the ones I used in the past.
Better example than mine. Although, another thing that I would add is changing void to a class T in the template.
-
I thought about that too, but I didn't remember the syntax for type templates in C++.
template <typename T>
class Array{
public:
virtual int getLength() = 0;
};
template <typename T, int size>
class StaticArray : public Array<T>
{
public:
T data[size];
virtual int getLength(){ return size; }
};
int main(){
StaticArray<int, 10> array;
return 0;
}
-
I thought about that too, but I didn't remember the syntax for type templates in C++.
template <typename T>
class Array{
public:
virtual int getLength() = 0;
};
template <typename T, int size>
class StaticArray : public Array<T>
{
public:
T data[size];
virtual int getLength(){ return size; }
};
int main(){
StaticArray<int, 10> array;
return 0;
}
What exactly is the point of the first class? It doesn't do anything, and you don't really need it.
-
Well, you could have this
int sum(Array<int>* numbers){
int result = 0;
for(int i = 0; i < numbers->getLength();++i){
result += numbers[i];
}
return result;
}
int main(){
StaticArray<int, 10> array1;
StaticArray<int, 20> array2;
printf("%d\n", sum(&array1) + sum(&array2));
return 0;
}
-
Basically, it links the different classes the template creates so they can behave as one class (which they pretty much are). Notice that the non-type parameters mean you have to generate a different version of the code for every size... isn't it more efficient space-wise (and time-wise, considering the virtual function) to just make the number a constructor parameter?
-
It was just an example. There might be better use cases.
Also, how do you declare an array size in a constructor without using operator new nor malloc/calloc?
-
The C++ implementation of templates generates a new copy of the code every time, which means that non-type parameters are especially non-useful. If runtime generics had non-type parameters, it might be more useful, but that's basically just moving the argument and it may or may not make anything clearer or easier.
Also:
class A {
int array[10];
};
-
Well, you could have this
int sum(Array<int>* numbers){
int result = 0;
for(int i = 0; i < numbers->getLength();++i){
result += numbers[i];
}
return result;
}
int main(){
StaticArray<int, 10> array1;
StaticArray<int, 20> array2;
printf("%d\n", sum(&array1) + sum(&array2));
return 0;
}
Also this:
template<class T,int size> int sum(array<T,size> numbers)
{
...
}
EDIT: Rusky, it's not really any more or less efficient. If anything, a template uses less space. And, it's usually a bit cleaner, sometimes.
-
No, they use more space. Every instantiation generates another copy of the code. That's multiple functions doing exactly the same thing, or close enough that you could just change a number at runtime to get the same effect.
-
Unfortunately, C/C++ arrays have no "length" property, unlike Java arrays. Hence the purpose of my code.
Of course, I could think of ways to optimize my Array/StaticArray classes.
-
Unfortunately, C/C++ arrays have no "length" property, unlike Java arrays. Hence the purpose of my code.
Of course, I could think of ways to optimize my Array/StaticArray classes.
That's because it would require storing it in another variable, using up space.
-
@RetroX I know C can be used in very limited environments and is quite old.
But nowadays, are 4 bytes per array really that harmful?
-
It's not that it's harmful, it's that it's not under your control. The whole idea of C and C++ is that you control everything. Make your own array with a length property if you need it, or use vector or something.
-
It's not that it's harmful, it's that it's not under your control. The whole idea of C and C++ is that you control everything. Make your own array with a length property if you need it, or use vector or something.
For once, I agree with what Rusky says.
-
Make your own array
In case you didn't notice, that's what I did in the template example above.
-
Exactly. You just did it with a non-class template parameter, which generates a new copy of all member functions for every size. Why not make it a property and pass it to the constructor?
-
Exactly. You just did it with a non-class template parameter, which generates a new copy of all member functions for every size. Why not make it a property and pass it to the constructor?
AFAIK, I thought that the point of templates is so that you don't waste size copying all of the functions. Meaning that it uses the template to make a function on runtime, or something, unless I'm wrong.
-
Quite the opposite. Templates (in theory) save lines of code, but increase actual executable size (disk and memory) due to the fact that the code is copied with only slight modification for each instantiation. A perk is that templated functions that go unused aren't included in the compiled product at all.
-
Templates are basically automated copy-and-pasting. They're in C++ because runtime generics would be completely against the philosophy of the language.
-
While it is true that templates can fill space in a horrible way, they can be very useful.
As miky pointed out, they are automated copy and pasting. So if you actually need copy and pasting, then templates are probably the best solution.
Templates are a way of doing metaprogramming in C++ (http://"http://en.wikipedia.org/wiki/Template_metaprogramming"). Not sure how useful that is, though.
Also, while it is true that templates copy-paste the code, that fact means the compiler can attempt more sophisticated tricks to improve runtime speed. So templates can improve speed at the expense of executable size.
-
Yes, templates are useful. But using then for different sizes of an array is just a waste. It's really not any faster to use a constant than a member. I guess if you only used inline functions it wouldn't be a problem, which is a possibility with simple containers. You'd just have to be really careful.
-
Yes, templates are useful. But using then for different sizes of an array is just a waste. It's really not any faster to use a constant than a member. I guess if you only used inline functions it wouldn't be a problem, which is a possibility with simple containers. You'd just have to be really careful.
Now that I actually know what templates do, I have to agree. Unfortunately, there is no storage for typename outside of templates. D:
Also:
template<class type1,class type2> function add(type x,type2 y)
{
return x+y;
}
int main()
{
int z=add('x',5);
return 0;
}
Terrible concept, but yeah.