- Using a lookup table at compile time - 7 Updates
- Using a lookup table at compile time - 9 Updates
- C++ Middleware Writer - 1 Update
- Convert char to int - 4 Updates
- what do people use for automated testing of C++ Windows app ? - 4 Updates
ram@zedat.fu-berlin.de (Stefan Ram): Aug 23 04:49PM >const int A::table[] = {0, 1, 2, 3, 4}; In this case, »table[ 0 ]« can be replace by »0«. In this case, »table[ 1 ]« can be replace by »1«. In this case, »table[ 2 ]« can be replace by »2«. In this case, »table[ 3 ]« can be replace by »3«. In this case, »table[ 4 ]« can be replace by »4«. |
ram@zedat.fu-berlin.de (Stefan Ram): Aug 23 04:51PM >const int A::table[] = {0, 1, 2, 3, 4}; #include <iostream> #include <ostream> #define TABLE0 0 #define TABLE1 1 #define TABLE2 2 #define TABLE3 3 #define TABLE4 4 #define TABLE(x) TABLE##x int main() { ::std::cout << TABLE( 0 )<< '\n'; ::std::cout << TABLE( 1 )<< '\n'; ::std::cout << TABLE( 2 )<< '\n'; ::std::cout << TABLE( 3 )<< '\n'; ::std::cout << TABLE( 4 )<< '\n'; } |
ram@zedat.fu-berlin.de (Stefan Ram): Aug 23 05:15PM >int y = x -'0'; >Is this the C++ 11 way of doing this or is there a better way? Should I >put x into a string of length 1 and use atoi? If you only ever have the value of »'8'« you can write int y = 8; . If you also have /other/ character values it depends on what you want them to be converted /into/. I think, one could give the intended mapping rule /in English/ and then we could figure out how to implement this rule in C++. |
ram@zedat.fu-berlin.de (Stefan Ram): Aug 23 07:56PM >Maybe that isnt't clear from the post, but it's supposed to be a lookup >table and also needs to work for dynamic lookups. #include <iostream> #include <ostream> #define F(i) i, #define TABLE \ F( 0 )\ F( 1 )\ F( 2 )\ F( 3 )\ F( 4 ) int array[] ={ TABLE }; #undef F #define F(i) TABLE##i=i, enum table { TABLE }; #undef F int main( void ) { switch( 0 ){ case TABLE0: int i = 0; ::std::cout << array[ 0 ]<< '\n'; }} |
ram@zedat.fu-berlin.de (Stefan Ram): Aug 23 08:00PM >F( 2 )\ >F( 3 )\ >F( 4 ) A superficial change: This, of course, can be written more compact as #define TABLE F(0)F(1)F(2)F(3)F(4) . |
ram@zedat.fu-berlin.de (Stefan Ram): Aug 23 08:20PM >#define F(i) TABLE##i=i, This would work only in the special case given. Here is a new, more general version: #include <iostream> #include <ostream> #define F(i,j) (j), #define TAB F(0,0)F(1,1)F(2,2)F(3,3)F(4,4) int array[] ={ TAB }; #undef F #define F(i,j) TAB##i=(j), enum table { TAB }; #undef F #define TABLE(i) TAB##i int main( void ) { int i; switch( 0 ){ case TABLE( 0 ): case TABLE( 1 ): case TABLE( 2 ): ; } ::std::cout << TABLE( 0 )<< '\n'; i = 0; ::std::cout << array[ i ]<< '\n'; ::std::cout << TABLE( 1 )<< '\n'; i = 1; ::std::cout << array[ i ]<< '\n'; ::std::cout << TABLE( 2 )<< '\n'; i = 2; ::std::cout << array[ i ]<< '\n'; } The programmer must choose himself to use »TABLE« for compile-time lookup and »array« for run-time lookup for each lookup case. |
ram@zedat.fu-berlin.de (Stefan Ram): Aug 23 09:29PM >The programmer must choose himself to use »TABLE« for compile-time lookup >and »array« for run-time lookup for each lookup case. The next program is a really ugly hack, where the programmer can write »TABLE( 0 )« for a compile-time value and »TABLE( i )« for a run-time value. But this is no general solution, it only works for the variable name »i«, which must be an int variable, and integer literals. #include <iostream> #include <ostream> #define F(i,j) (j), #define TAB F(0,0)F(1,1)F(2,2)F(3,3)F(4,4) int array[] ={ TAB }; #undef F #define F(i,j) TAB##i=(j), enum table { TAB }; #undef F #define TABLE(i) TAB##i #define TABi ((array)[(i)]) int main( void ) { int i; switch( 0 ){ case TABLE( 0 ): case TABLE( 1 ): case TABLE( 2 ): ; } ::std::cout << TABLE( 0 )<< '\n'; i = 0; ::std::cout << TABLE( i )<< '\n'; ::std::cout << TABLE( 1 )<< '\n'; i = 1; ::std::cout << TABLE( i )<< '\n'; ::std::cout << TABLE( 2 )<< '\n'; i = 2; ::std::cout << TABLE( i )<< '\n'; } |
mark <mark@invalid.invalid>: Aug 23 05:53PM +0200 What is a good way to use a lookup table at compile time? Using C++11 is not an option (must work with GCC 4.3). This is for embedded usage with tiny amounts of memory and every byte counts. Having increased code or data size compared to hardcoding things is not an option. E.g: --------------------------------------------------- class A { public: void m(); private: static const int table[5]; }; void A::m() { int arr[table[3]]; // table[3] is not compile time const } const int A::table[] = {0, 1, 2, 3, 4}; --------------------------------------------------- |
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Aug 23 12:08PM -0700 On Tuesday, August 23, 2016 at 11:54:01 AM UTC-4, mark wrote: > } > const int A::table[] = {0, 1, 2, 3, 4}; > --------------------------------------------------- I was surprised nobody's replied by now. I'm not sure what the best way to do it in C++ is, but if you know explicitly these constants at compile-time, such that you're referencing table[3], then you could use an enum like this: class A { public: void m(); private: enum { first = 0, one, two, three, four }; }; void A::m() { int arr[A::three]; // A::three is a compile time const } ----- You could also define compile-time constants for the values 0, 1, 2, 3, and 4, and define constants which reference those constants using a similar name, like...: #define _const0 0 #define _const1 1 #define _const2 2 #define _const3 3 #define _const4 4 const int A::table[] = {_const0, _const1, _const2, _const3, _const4}; #define table0 _const0 #define table1 _const1 #define table2 _const2 #define table3 _const3 #define table4 _const4 ...so that instead of using "table[3]" you'd use "table3" which would map to the same constant value: int arr[table3]; // Make sure table3's declared ahead of use These are the solutions I would use if I had constraints. I am, however, curious what the proper C++ solution is. Best regards, Rick C. Hodgin |
mark <mark@invalid.invalid>: Aug 23 09:26PM +0200 On 2016-08-23 18:51, Stefan Ram wrote: > ::std::cout << TABLE( 2 )<< '\n'; > ::std::cout << TABLE( 3 )<< '\n'; > ::std::cout << TABLE( 4 )<< '\n'; } Maybe that isnt't clear from the post, but it's supposed to be a lookup table and also needs to work for dynamic lookups. I.e.: void A::m2(int i) { return table[i] * 42; } needs to work. |
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Aug 23 12:36PM -0700 On Tuesday, August 23, 2016 at 3:27:04 PM UTC-4, mark wrote: > return table[i] * 42; > } > needs to work. The second solution I provided would allow your option here to work. It simply migrates the constant values from being specified in the { ... } definition into #define tokens, but it still creates table. #define _const0 0 #define _const1 1 #define _const2 2 #define _const3 3 #define _const4 4 const int A::table[] = {_const0, _const1, _const2, _const3, _const4}; #define table0 _const0 #define table1 _const1 #define table2 _const2 #define table3 _const3 #define table4 _const4 void A::m() { int arr[table3]; } void A::m2(int i) { return table[i] * 42; } Both would be valid. Best regards, Rick C. Hodgin |
mark <mark@invalid.invalid>: Aug 23 09:44PM +0200 On 2016-08-23 21:08, Rick C. Hodgin wrote: > int arr[table3]; // Make sure table3's declared ahead of use > These are the solutions I would use if I had constraints. I am, however, > curious what the proper C++ solution is. Thank's. I was hoping for something more elegant. |
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Aug 23 12:49PM -0700 On Tuesday, August 23, 2016 at 3:44:21 PM UTC-4, mark wrote: > > These are the solutions I would use if I had constraints. I am, however, > > curious what the proper C++ solution is. > Thank's. I was hoping for something more elegant. Well, I'm sure someone else will be able to provide you with a more elegant solution. I apologize if my offering offended you. Best regards, Rick C. Hodgin |
legalize+jeeves@mail.xmission.com (Richard): Aug 23 08:00PM [Please do not mail me a copy of your followup] First, let me say that you've posed a very specific question with a generic example in the form of "how do I perform this task?" but you haven't told us the actual goal the task is supposed to accomplish. Eric Raymond calls this "describe the goal, not the step". Here you've described the step and not the goal. If we knew the goal, we could probably advise you more fully on the best way to achieve it. <http://www.catb.org/esr/faqs/smart-questions.html#goal> Let's proceed... mark <mark@invalid.invalid> spake the secret code >What is a good way to use a lookup table at compile time? An easier solution might be to simply generate source files at build time that reflect whatever it is you're trying to do at compile time. Compile-time evaluation occurs through one of two C++ mechanisms: templates and constexpr. Since you are using an ancient gcc, you can't use constexpr. That leaves templates. (I'm ignoring preprocessor hacks, I'm sure someone else will post a disgusting solution using macros.) Templates can implement a table-lookup type mechanism through a generic template and one specialization of the generic template for each input to the lookup. The outputs are obtained through the differences in the specializations. > int arr[table[3]]; // table[3] is not compile time const >} >const int A::table[] = {0, 1, 2, 3, 4}; template <int Index> struct table { static const int value; }; template <> struct table<0> { static const int value = 0; }; template <> struct table<1> { static const int value = 1; }; template <> struct table<2> { static const int value = 2; }; template <> struct table<3> { static const int value = 3; }; template <> struct table<4> { static const int value = 4; }; class A { public: void m(); }; void A::m() { int arr[table<3>::value]; for (int i = 0; i < sizeof(arr)/sizeof(int); ++i) { arr[i] = 2*i; } } int main() { A a; a.m(); } So yeah, that works, but it's pretty noisy. -- "The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline> The Computer Graphics Museum <http://computergraphicsmuseum.org> The Terminals Wiki <http://terminals.classiccmp.org> Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com> |
mark <mark@invalid.invalid>: Aug 23 11:06PM +0200 On 2016-08-23 21:49, Rick C. Hodgin wrote: >> > Thank's. I was hoping for something more elegant. > Well, I'm sure someone else will be able to provide you with a more > elegant solution. I apologize if my offering offended you. This wasn't intended to be ironic or anything. Your second suggestion may very well be what I will use. Which doesn't mean I'm happy with it, what I really want is something like: class A { public: void m(); int m2(int v); int m3(int v); private: static constexpr int table[5] = { 4, 1, 7, 2, 1 }; static constexpr int i = table[2]; }; void A::m() { int arr[table[3]]; } int A::m2(int v) { return table[v] * 42; } int A::m3(int v) { switch(v) { case table[2]: return 42; default: return -1; } } |
mark <mark@invalid.invalid>: Aug 23 11:25PM +0200 On 2016-08-23 22:20, Stefan Ram wrote: > ::std::cout << TABLE( 2 )<< '\n'; i = 2; ::std::cout << array[ i ]<< '\n'; } > The programmer must choose himself to use »TABLE« for compile-time lookup > and »array« for run-time lookup for each lookup case. Wow, some neat macro (ab)use. I'm not sure other people will be thrilled, if I use something like that. |
Dombo <dombo@disposable.invalid>: Aug 23 10:11PM +0200 Op 21-Aug-16 om 11:19 schreef jacob navia: >> Isn't it just a description of anyone else's code? :-) > If after 15+ years the code is like that, imagine after just a few > MILLION years... After a few million years some of the people looking at the code will conclude there must be an intelligent design behind it and that the first lines of code were conceived about 6000 years before ;-) |
Joseph Hesse <joeh@gmail.com>: Aug 23 12:05PM -0500 I have a char x = '8' and want to use this to put the integer 8 into an int variable. I know I can do it this way: char x = '8'; int y = x -'0'; Is this the C++ 11 way of doing this or is there a better way? Should I put x into a string of length 1 and use atoi? Thank you, Joe |
Victor Bazarov <v.bazarov@comcast.invalid>: Aug 23 01:23PM -0400 On 8/23/2016 1:05 PM, Joseph Hesse wrote: > int y = x -'0'; > Is this the C++ 11 way of doing this or is there a better way? Should I > put x into a string of length 1 and use atoi? There is no need for atoi. The C++ character set works the way you showed for all decimal digits. V -- I do not respond to top-posted replies, please don't ask |
scott@slp53.sl.home (Scott Lurndal): Aug 23 07:28PM >> put x into a string of length 1 and use atoi? >There is no need for atoi. The C++ character set works the way you >showed for all decimal digits. C++ character set? In reality, whether the underlying encoding is ASCII, EBCDIC or UTF-8, the technique of subtracting the character '0' from any other numeric character value will work properly. |
Victor Bazarov <v.bazarov@comcast.invalid>: Aug 23 03:38PM -0400 On 8/23/2016 3:28 PM, Scott Lurndal wrote: >> showed for all decimal digits. > C++ character set? > [.. blahblah ..] Yes, please see the Standard, [lex.charset]. The first paragraph starts with "The /basic character set/ consists". V -- I do not respond to top-posted replies, please don't ask |
David Brown <david.brown@hesbynett.no>: Aug 23 08:59AM +0200 On 23/08/16 00:57, Öö Tiib wrote: > worldwide". Why google is better than others? Amazon pays taxes, oracle > pays taxes, microsoft pays taxes, apple pays taxes. Google should pay > taxes too. I agree that Google should pay taxes - but none of these other companies pays taxes in the way small companies or individuals do. They /all/ have armies of lawyers and accountants whose job is to minimise the taxes paid, to make sure profits are shuffled around from company to company and country to country until tax authorities have lost track. /None/ of them pay an appropriate level of tax in the countries where they make they money. So while I fully agree that Google is bad at this, it is no worse than the other big IT companies. > They indeed have a odd religion against C++ exceptions. So if other > frameworks did not compile with exceptions turned off then they had > to make their own. Google are not alone in disliking C++ exceptions - it is a better attitude than many C++ programmers who write code that occasionally uses exceptions, but don't really understand all the details needed to make properly exception-safe code, or who treat exceptions as just a way of giving the user an error message when something goes wrong. |
Lynn McGuire <lynnmcguire5@gmail.com>: Aug 22 12:49PM -0500 On 8/20/2016 5:20 PM, Lynn McGuire wrote: > http://stackoverflow.com/questions/1287425/automated-testing-for-c-c-gui-applications > Thanks, > Lynn Interesting article, "Why Are There So Many C++ Testing Frameworks?": http://googletesting.blogspot.com/2012/10/why-are-there-so-many-c-testing.html Lynn |
legalize+jeeves@mail.xmission.com (Richard): Aug 22 07:54PM [Please do not mail me a copy of your followup] Lynn McGuire <lynnmcguire5@gmail.com> spake the secret code >Interesting article, "Why Are There So Many C++ Testing Frameworks?": >http://googletesting.blogspot.com/2012/10/why-are-there-so-many-c-testing.html Without reading the article, my guesses are: - there wasn't one, so we made our own and kept using it - open source egoism[*] - there's no defacto standard like jUnit - framework PQR doesn't do enough, so I made my own - framework PQR does too much, so I made my own Now let's go look at the article and see how I did. Google says PQR doesn't do enough, so they made their own: "The short answer is that we couldn't find an existing C++ testing framework that satisfied all our needs." Which frankly I find hard to believe because there isn't anything in GTest that wasn't already in Boost.Test AFAICT. Maybe it was the use of exceptions they didn't like, I can't recall if Boost.Test relies on exceptions or simply supports testing code that uses them. [*] "open source egoism" is what I call the phenomenon of what motivates people to contribute to open source. It's much sexier to create your own thing from scratch than it is to do bug fixes on an existing thing or enhance/extend an existing thing. Therefore, open source software development tends to result in lots of greenfield projects that do just enough to scratch the author's itch and they don't build a community that extends them further. Therefore a profusion of small greenfield projects appear, but none of them is sufficiently embraced to gain dominance. -- "The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline> The Computer Graphics Museum <http://computergraphicsmuseum.org> The Terminals Wiki <http://terminals.classiccmp.org> Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com> |
Lynn McGuire <lynnmcguire5@gmail.com>: Aug 22 03:36PM -0500 On 8/22/2016 2:54 PM, Richard wrote: > don't build a community that extends them further. Therefore a > profusion of small greenfield projects appear, but none of them is > sufficiently embraced to gain dominance. And they are Google. Lynn |
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page. To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com. |
No comments:
Post a Comment