Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. Other Discussions
  3. Clever Code
  4. Simulating C++0x literals - with enums!

Simulating C++0x literals - with enums!

Scheduled Pinned Locked Moved Clever Code
questionc++comalgorithmsdiscussion
18 Posts 11 Posters 45 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • P Offline
    P Offline
    peterchen
    wrote on last edited by
    #1

    Sure enough a few days after ranting about the pointless complexity of User-defined literals[^] in C++0x, I have an applicaiton that could use it. for a custom numeric formatter (think "pimp my %f"), I support three explicit modes for precision: absolute, relative and scaling (similar to to %g). In application, precision usually needs to be specified individually for each value to be printed, so how do I stop myself from having tons of: FmtX(fmtspec, value, CPrecision(2,pmRelative)) spread throughout my code? Sure enough, there's a solution, and you will probably not like it:

    CPrecision operator -(int precision, EPrecisionMode pm) { return CPrecision(precision, pm); }
    ...
    FmtX(fmtspec, value, 2-pmRelative);

    I am not quite sure if I should be proud, or ashamed. But "Wicked code" seems about right. What do you think?

    Don't attribute to stupidity what can be equally well explained by buerocracy.
    My latest article | Linkify!| FoldWithUs! | sighist

    P A D J M 7 Replies Last reply
    0
    • P peterchen

      Sure enough a few days after ranting about the pointless complexity of User-defined literals[^] in C++0x, I have an applicaiton that could use it. for a custom numeric formatter (think "pimp my %f"), I support three explicit modes for precision: absolute, relative and scaling (similar to to %g). In application, precision usually needs to be specified individually for each value to be printed, so how do I stop myself from having tons of: FmtX(fmtspec, value, CPrecision(2,pmRelative)) spread throughout my code? Sure enough, there's a solution, and you will probably not like it:

      CPrecision operator -(int precision, EPrecisionMode pm) { return CPrecision(precision, pm); }
      ...
      FmtX(fmtspec, value, 2-pmRelative);

      I am not quite sure if I should be proud, or ashamed. But "Wicked code" seems about right. What do you think?

      Don't attribute to stupidity what can be equally well explained by buerocracy.
      My latest article | Linkify!| FoldWithUs! | sighist

      P Offline
      P Offline
      PIEBALDconsult
      wrote on last edited by
      #2

      Wow, almost an Extension Method. :-D

      1 Reply Last reply
      0
      • P peterchen

        Sure enough a few days after ranting about the pointless complexity of User-defined literals[^] in C++0x, I have an applicaiton that could use it. for a custom numeric formatter (think "pimp my %f"), I support three explicit modes for precision: absolute, relative and scaling (similar to to %g). In application, precision usually needs to be specified individually for each value to be printed, so how do I stop myself from having tons of: FmtX(fmtspec, value, CPrecision(2,pmRelative)) spread throughout my code? Sure enough, there's a solution, and you will probably not like it:

        CPrecision operator -(int precision, EPrecisionMode pm) { return CPrecision(precision, pm); }
        ...
        FmtX(fmtspec, value, 2-pmRelative);

        I am not quite sure if I should be proud, or ashamed. But "Wicked code" seems about right. What do you think?

        Don't attribute to stupidity what can be equally well explained by buerocracy.
        My latest article | Linkify!| FoldWithUs! | sighist

        A Offline
        A Offline
        Adam Maras
        wrote on last edited by
        #3

        This has definitely been filed in my "stupid C++ tricks" collection. Brilliant! :)

        1 Reply Last reply
        0
        • P peterchen

          Sure enough a few days after ranting about the pointless complexity of User-defined literals[^] in C++0x, I have an applicaiton that could use it. for a custom numeric formatter (think "pimp my %f"), I support three explicit modes for precision: absolute, relative and scaling (similar to to %g). In application, precision usually needs to be specified individually for each value to be printed, so how do I stop myself from having tons of: FmtX(fmtspec, value, CPrecision(2,pmRelative)) spread throughout my code? Sure enough, there's a solution, and you will probably not like it:

          CPrecision operator -(int precision, EPrecisionMode pm) { return CPrecision(precision, pm); }
          ...
          FmtX(fmtspec, value, 2-pmRelative);

          I am not quite sure if I should be proud, or ashamed. But "Wicked code" seems about right. What do you think?

          Don't attribute to stupidity what can be equally well explained by buerocracy.
          My latest article | Linkify!| FoldWithUs! | sighist

          D Offline
          D Offline
          dighn
          wrote on last edited by
          #4

          Ahh the wonders of operator overloading :laugh:

          1 Reply Last reply
          0
          • P peterchen

            Sure enough a few days after ranting about the pointless complexity of User-defined literals[^] in C++0x, I have an applicaiton that could use it. for a custom numeric formatter (think "pimp my %f"), I support three explicit modes for precision: absolute, relative and scaling (similar to to %g). In application, precision usually needs to be specified individually for each value to be printed, so how do I stop myself from having tons of: FmtX(fmtspec, value, CPrecision(2,pmRelative)) spread throughout my code? Sure enough, there's a solution, and you will probably not like it:

            CPrecision operator -(int precision, EPrecisionMode pm) { return CPrecision(precision, pm); }
            ...
            FmtX(fmtspec, value, 2-pmRelative);

            I am not quite sure if I should be proud, or ashamed. But "Wicked code" seems about right. What do you think?

            Don't attribute to stupidity what can be equally well explained by buerocracy.
            My latest article | Linkify!| FoldWithUs! | sighist

            J Offline
            J Offline
            Jim Crafton
            wrote on last edited by
            #5

            Utterly and completely hideous! :) Nearly on par with associating reading and writing data with binary bit shift operators... :omg:

            ¡El diablo está en mis pantalones! ¡Mire, mire! SELECT * FROM User WHERE Clue > 0 0 rows returned Save an Orange - Use the VCF! Personal 3D projects Just Say No to Web 2 Point Oh

            S 1 Reply Last reply
            0
            • J Jim Crafton

              Utterly and completely hideous! :) Nearly on par with associating reading and writing data with binary bit shift operators... :omg:

              ¡El diablo está en mis pantalones! ¡Mire, mire! SELECT * FROM User WHERE Clue > 0 0 rows returned Save an Orange - Use the VCF! Personal 3D projects Just Say No to Web 2 Point Oh

              S Offline
              S Offline
              supercat9
              wrote on last edited by
              #6

              Jim Crafton wrote:

              Utterly and completely hideous!Nearly on par with associating reading and writing data with binary bit shift operators...

              I'm reminded of a "Why C is better than Pascal/Why Pascal is better than C" document I saw a couple decades ago. Among other things, C is better than Pascal because you can write (some small incomprehensible mass of stuff to, I think, draw a rectangle in ASCII characters). Pascal is better than C because you can't write (same mass of stuff). One of the major differences between C++ and C# is that the latter explicitly does not support the types of preprocessor "abuse" for which the former is so famous. In some ways I like those hacks; in other ways I don't. The C preprocessor can do many things, but it also has some pretty severe limitations. Once nice bit of preprocessor hacking I did awhile ago was to arrange things so if I define a macro as "X(label1) Y X(label2) Y X(label3) X(label4)" (without the quotes) the preprocessor will automatically generate enumerations NF_label1=0, FN_label2=1, FN_label2=1, etc. (consecutive numbers), along with FL_label1=1, FL_label2=2, FL_label3=4, etc. (powers of two), a structure containing some flags as well as an int for each label, and even code inside a routine for each label "tim.label1 -=n; if (tim.label1 > n) tim.flags |= FL_label1;", etc. (on the target system, performance with a loop would be unacceptable). Preprocessor abuse? Probably. But is there any better way to achieve such results without having to list the labels multiple times, and risking trouble if the different lists don't match?

              G P 2 Replies Last reply
              0
              • P peterchen

                Sure enough a few days after ranting about the pointless complexity of User-defined literals[^] in C++0x, I have an applicaiton that could use it. for a custom numeric formatter (think "pimp my %f"), I support three explicit modes for precision: absolute, relative and scaling (similar to to %g). In application, precision usually needs to be specified individually for each value to be printed, so how do I stop myself from having tons of: FmtX(fmtspec, value, CPrecision(2,pmRelative)) spread throughout my code? Sure enough, there's a solution, and you will probably not like it:

                CPrecision operator -(int precision, EPrecisionMode pm) { return CPrecision(precision, pm); }
                ...
                FmtX(fmtspec, value, 2-pmRelative);

                I am not quite sure if I should be proud, or ashamed. But "Wicked code" seems about right. What do you think?

                Don't attribute to stupidity what can be equally well explained by buerocracy.
                My latest article | Linkify!| FoldWithUs! | sighist

                M Offline
                M Offline
                Moreno Airoldi
                wrote on last edited by
                #7

                Sure is wicked hehe! :)

                2+2=5 for very large amounts of 2 (always loved that one hehe!)

                1 Reply Last reply
                0
                • S supercat9

                  Jim Crafton wrote:

                  Utterly and completely hideous!Nearly on par with associating reading and writing data with binary bit shift operators...

                  I'm reminded of a "Why C is better than Pascal/Why Pascal is better than C" document I saw a couple decades ago. Among other things, C is better than Pascal because you can write (some small incomprehensible mass of stuff to, I think, draw a rectangle in ASCII characters). Pascal is better than C because you can't write (same mass of stuff). One of the major differences between C++ and C# is that the latter explicitly does not support the types of preprocessor "abuse" for which the former is so famous. In some ways I like those hacks; in other ways I don't. The C preprocessor can do many things, but it also has some pretty severe limitations. Once nice bit of preprocessor hacking I did awhile ago was to arrange things so if I define a macro as "X(label1) Y X(label2) Y X(label3) X(label4)" (without the quotes) the preprocessor will automatically generate enumerations NF_label1=0, FN_label2=1, FN_label2=1, etc. (consecutive numbers), along with FL_label1=1, FL_label2=2, FL_label3=4, etc. (powers of two), a structure containing some flags as well as an int for each label, and even code inside a routine for each label "tim.label1 -=n; if (tim.label1 > n) tim.flags |= FL_label1;", etc. (on the target system, performance with a loop would be unacceptable). Preprocessor abuse? Probably. But is there any better way to achieve such results without having to list the labels multiple times, and risking trouble if the different lists don't match?

                  G Offline
                  G Offline
                  Gary R Wheeler
                  wrote on last edited by
                  #8

                  supercat9 wrote:

                  differences between C++ and C# is that the latter explicitly does not support the types of preprocessor "abuse" for which the former is so famous

                  Like goto, #define is one of those tools that a lot of programmers don't have sufficient experience and discretion to know when to use it, and when not to use it. Other than manifest constants and conditional compilation (which even C# supports), I've always found the key to using the preprocessor was to ask two simple questions: 1. Does using #define make the code easier to write correctly and easier to read? Most code that abuses the preprocessor stops with the first part of the question, and misses the second part. Any time you find yourself evaluating a macro in your head in order to understand the code, the #define is a mistake. 2. Can the macro be written effectively as 'ordinary' code? If so, then write it that way. Note the word 'effectively'. If writing the macro as ordinary code obscures the functionality too much, or increases the burden on the user too far, then maybe the macro is the better way to go. For me, the answer to Q1 must be yes, and Q2 must be no.

                  Software Zen: delete this;
                  Fold With Us![^]

                  S P 2 Replies Last reply
                  0
                  • P peterchen

                    Sure enough a few days after ranting about the pointless complexity of User-defined literals[^] in C++0x, I have an applicaiton that could use it. for a custom numeric formatter (think "pimp my %f"), I support three explicit modes for precision: absolute, relative and scaling (similar to to %g). In application, precision usually needs to be specified individually for each value to be printed, so how do I stop myself from having tons of: FmtX(fmtspec, value, CPrecision(2,pmRelative)) spread throughout my code? Sure enough, there's a solution, and you will probably not like it:

                    CPrecision operator -(int precision, EPrecisionMode pm) { return CPrecision(precision, pm); }
                    ...
                    FmtX(fmtspec, value, 2-pmRelative);

                    I am not quite sure if I should be proud, or ashamed. But "Wicked code" seems about right. What do you think?

                    Don't attribute to stupidity what can be equally well explained by buerocracy.
                    My latest article | Linkify!| FoldWithUs! | sighist

                    G Offline
                    G Offline
                    Gary R Wheeler
                    wrote on last edited by
                    #9

                    I probably would have chosen the division operator '/' myself. You say toe-mah-toe, I say toe-may-toe.

                    Software Zen: delete this;
                    Fold With Us![^]

                    P 1 Reply Last reply
                    0
                    • G Gary R Wheeler

                      supercat9 wrote:

                      differences between C++ and C# is that the latter explicitly does not support the types of preprocessor "abuse" for which the former is so famous

                      Like goto, #define is one of those tools that a lot of programmers don't have sufficient experience and discretion to know when to use it, and when not to use it. Other than manifest constants and conditional compilation (which even C# supports), I've always found the key to using the preprocessor was to ask two simple questions: 1. Does using #define make the code easier to write correctly and easier to read? Most code that abuses the preprocessor stops with the first part of the question, and misses the second part. Any time you find yourself evaluating a macro in your head in order to understand the code, the #define is a mistake. 2. Can the macro be written effectively as 'ordinary' code? If so, then write it that way. Note the word 'effectively'. If writing the macro as ordinary code obscures the functionality too much, or increases the burden on the user too far, then maybe the macro is the better way to go. For me, the answer to Q1 must be yes, and Q2 must be no.

                      Software Zen: delete this;
                      Fold With Us![^]

                      S Offline
                      S Offline
                      supercat9
                      wrote on last edited by
                      #10

                      Gary R. Wheeler wrote:

                      1. Does using #define make the code easier to write correctly and easier to read?

                      I'd include 'modify' as an important criterion. In some cases, certain uses of macros can make code easy to write, and easy to modify, even if it's difficult to read. For example, which of the following styles (typed from memory) seems easier to read:

                      /* ub == unsigned byte; ui = unsigned 16-bit integer; ul = unsigned 32-bit integer */
                      struct {
                      ub format;
                      ub this;
                      ui that;
                      ul whatever;
                      ...
                      } MY_THING;

                      const MY_THING default_my_thing = {5,2,5,199, ...};

                      Putting the default values of all the parameters in a list after the end of the definition, or...

                      /* Structure definition must be on one "line"...
                      (extend the line with backslashes). X must appear after every item but the last. */
                      #define MAKE_MY_THING \
                      ITEM(ub format, 5) X\
                      ITEM(ub this, 2) X\
                      ITEM(ui that, 5) X\
                      ITEM(ul whatever, 199) X\
                      ...

                      The MAKE_MY_THING macro can then be invoked twice--once to define the structure, and once to create the default instance (the definitions of ITEM and X will change between the invocations). I wouldn't consider that code to be particularly easy to decipher, but when I switched from the former style to the latter style, I stopped having problems with mis-aligned parameters. The biggest annoyance is that if the initializer for a structure item commas, it must be defined in a separate macro. I would regard that code as easier to write and modify than the "normal" method; harder to decipher, but IMHO worth the trouble. BTW, in this particular application constant storage was separate from variable storage, so having the variable be non-const and initializing it at run-time would not have been a good option.

                      1 Reply Last reply
                      0
                      • G Gary R Wheeler

                        I probably would have chosen the division operator '/' myself. You say toe-mah-toe, I say toe-may-toe.

                        Software Zen: delete this;
                        Fold With Us![^]

                        P Offline
                        P Offline
                        peterchen
                        wrote on last edited by
                        #11

                        I've picked '-' for it's proximity to the hyphen (and we germans are known to hyphenate a lot..)

                        Don't attribute to stupidity what can be equally well explained by buerocracy.
                        My latest article | Linkify!| FoldWithUs! | sighist

                        1 Reply Last reply
                        0
                        • S supercat9

                          Jim Crafton wrote:

                          Utterly and completely hideous!Nearly on par with associating reading and writing data with binary bit shift operators...

                          I'm reminded of a "Why C is better than Pascal/Why Pascal is better than C" document I saw a couple decades ago. Among other things, C is better than Pascal because you can write (some small incomprehensible mass of stuff to, I think, draw a rectangle in ASCII characters). Pascal is better than C because you can't write (same mass of stuff). One of the major differences between C++ and C# is that the latter explicitly does not support the types of preprocessor "abuse" for which the former is so famous. In some ways I like those hacks; in other ways I don't. The C preprocessor can do many things, but it also has some pretty severe limitations. Once nice bit of preprocessor hacking I did awhile ago was to arrange things so if I define a macro as "X(label1) Y X(label2) Y X(label3) X(label4)" (without the quotes) the preprocessor will automatically generate enumerations NF_label1=0, FN_label2=1, FN_label2=1, etc. (consecutive numbers), along with FL_label1=1, FL_label2=2, FL_label3=4, etc. (powers of two), a structure containing some flags as well as an int for each label, and even code inside a routine for each label "tim.label1 -=n; if (tim.label1 > n) tim.flags |= FL_label1;", etc. (on the target system, performance with a loop would be unacceptable). Preprocessor abuse? Probably. But is there any better way to achieve such results without having to list the labels multiple times, and risking trouble if the different lists don't match?

                          P Offline
                          P Offline
                          PIEBALDconsult
                          wrote on last edited by
                          #12

                          There's really nothing keeping you from using the C preprocessor with C#, VB, or any language; it's just a text processor.

                          1 Reply Last reply
                          0
                          • G Gary R Wheeler

                            supercat9 wrote:

                            differences between C++ and C# is that the latter explicitly does not support the types of preprocessor "abuse" for which the former is so famous

                            Like goto, #define is one of those tools that a lot of programmers don't have sufficient experience and discretion to know when to use it, and when not to use it. Other than manifest constants and conditional compilation (which even C# supports), I've always found the key to using the preprocessor was to ask two simple questions: 1. Does using #define make the code easier to write correctly and easier to read? Most code that abuses the preprocessor stops with the first part of the question, and misses the second part. Any time you find yourself evaluating a macro in your head in order to understand the code, the #define is a mistake. 2. Can the macro be written effectively as 'ordinary' code? If so, then write it that way. Note the word 'effectively'. If writing the macro as ordinary code obscures the functionality too much, or increases the burden on the user too far, then maybe the macro is the better way to go. For me, the answer to Q1 must be yes, and Q2 must be no.

                            Software Zen: delete this;
                            Fold With Us![^]

                            P Offline
                            P Offline
                            PIEBALDconsult
                            wrote on last edited by
                            #13

                            A few months ago I was working playing with some code (C#) that I wanted to be very fast. There was a sequence of statements that I needed in two places. I didn't want to have to maintain two copies and I didn't want the overhead of a method (and wasn't sure it would be inlined), so I wrote a macro and used the C preprocessor.

                            S G 2 Replies Last reply
                            0
                            • P PIEBALDconsult

                              A few months ago I was working playing with some code (C#) that I wanted to be very fast. There was a sequence of statements that I needed in two places. I didn't want to have to maintain two copies and I didn't want the overhead of a method (and wasn't sure it would be inlined), so I wrote a macro and used the C preprocessor.

                              S Offline
                              S Offline
                              supercat9
                              wrote on last edited by
                              #14

                              PIEBALDconsult wrote:

                              (C#)...so I wrote a macro and used the C preprocessor.

                              I thought C# didn't allow anything "fun" within a macro. Or did you invoke the preprocessor separately? One thing I've sometimes been pondering is whether it would be worthwhile to write a preprocessor that would pull out string literals and do magical mystical things with them; I do a lot of embedded systems work, and some projects would benefit from: -1- Mapping strings to different character sets, since not everything in the world uses ASCII. -2- Packing or compressing strings via various methods, so as to save code space. -3- Pulling strings out of the code and storing them in a separate file. Generally I've handled all string munging in a process separate from my code builds. On the other hand, I've sometimes wondered whether it would make sense to write my own preprocessor to sit between the C preprocessor and the compiler. BTW, another item I'd add to the list, if I could figure out how to actually make it work, would be to convert "printf"-style calls to the most efficient form for the microcontrollers I use. On something like the PIC-18 series, all variables, including automatic ones, are allocated at fixed addresses. Further, a called function can manipulate the call/return stack. Thus, something like:

                              ; printf("Hello %04d %08lX %02X",intvar,longvar,bytevar & 0x7F);
                              movlw <msg
                              movwf ?printf_ptr
                              movlw >msg
                              movwf ?printf_ptr+1
                              movf _intvar,w
                              movwf ?varparam
                              movf >_intvar+1,w
                              movwf ?varparam+1
                              movf _longvar,w
                              movwf ?varparam+2
                              movf _longvar+1,w
                              movwf ?varparam+3
                              movf _longvar+2,w
                              movwf ?varparam+4
                              movf _longvar+3,w
                              movwf ?varparam+5
                              movf _bytevar,w
                              andlw 0x7F
                              movwf ?varparam+6
                              clrf ?varparam+7
                              call _printf ; High byte of last parameter</pre>
                              ...
                              msg "Hello %04d %08lX %02X",0

                              which is 22 instructions plus 30 bytes of data (74 bytes total) could become something like:

                              ; printf("Hello %04d %08lX %02X",intvar,longvar,bytevar & 0x7F);
                              movf _bytevar,w ; The only variable in a non-trivial expression
                              andlw 0x7F
                              movwf ?varparam
                              call _doformat
                              byte "Hello "
                              byte 0x81,0x44,>_intvar,<_intvar
                              byte " "
                              byte 0x82,0xC8,>_longvar,<_longvarvar
                              byte " "
                              byte 0x84,0xC2 ; Use byte from varparam
                              byte 0,0 ; Second zero needed if odd number of bytes
                              ; Next in

                              1 Reply Last reply
                              0
                              • P PIEBALDconsult

                                A few months ago I was working playing with some code (C#) that I wanted to be very fast. There was a sequence of statements that I needed in two places. I didn't want to have to maintain two copies and I didn't want the overhead of a method (and wasn't sure it would be inlined), so I wrote a macro and used the C preprocessor.

                                G Offline
                                G Offline
                                Gary R Wheeler
                                wrote on last edited by
                                #15

                                :omg:

                                Software Zen: delete this;
                                Fold With Us![^]

                                S 1 Reply Last reply
                                0
                                • G Gary R Wheeler

                                  :omg:

                                  Software Zen: delete this;
                                  Fold With Us![^]

                                  S Offline
                                  S Offline
                                  Shakti shakti
                                  wrote on last edited by
                                  #16

                                  how to hack in my system

                                  0 1 Reply Last reply
                                  0
                                  • S Shakti shakti

                                    how to hack in my system

                                    0 Offline
                                    0 Offline
                                    0x3c0
                                    wrote on last edited by
                                    #17

                                    Buy an axe

                                    Between the idea And the reality Between the motion And the act Falls the Shadow

                                    1 Reply Last reply
                                    0
                                    • P peterchen

                                      Sure enough a few days after ranting about the pointless complexity of User-defined literals[^] in C++0x, I have an applicaiton that could use it. for a custom numeric formatter (think "pimp my %f"), I support three explicit modes for precision: absolute, relative and scaling (similar to to %g). In application, precision usually needs to be specified individually for each value to be printed, so how do I stop myself from having tons of: FmtX(fmtspec, value, CPrecision(2,pmRelative)) spread throughout my code? Sure enough, there's a solution, and you will probably not like it:

                                      CPrecision operator -(int precision, EPrecisionMode pm) { return CPrecision(precision, pm); }
                                      ...
                                      FmtX(fmtspec, value, 2-pmRelative);

                                      I am not quite sure if I should be proud, or ashamed. But "Wicked code" seems about right. What do you think?

                                      Don't attribute to stupidity what can be equally well explained by buerocracy.
                                      My latest article | Linkify!| FoldWithUs! | sighist

                                      E Offline
                                      E Offline
                                      exyyle
                                      wrote on last edited by
                                      #18

                                      You spelled "bureaucracy" incorrectly.

                                      1 Reply Last reply
                                      0
                                      Reply
                                      • Reply as topic
                                      Log in to reply
                                      • Oldest to Newest
                                      • Newest to Oldest
                                      • Most Votes


                                      • Login

                                      • Don't have an account? Register

                                      • Login or register to search.
                                      • First post
                                        Last post
                                      0
                                      • Categories
                                      • Recent
                                      • Tags
                                      • Popular
                                      • World
                                      • Users
                                      • Groups