Skip to content

Commit

Permalink
Always generate 'vector' and 'list' traits for repeated fields
Browse files Browse the repository at this point in the history
  • Loading branch information
brunexgeek committed Mar 6, 2020
1 parent fe4186b commit b8e4bcb
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 22 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,16 @@ Person person;
Person::ErrorInfo err;
if (!person.deserialize(json, false, &err))
std::cerr << "Error: " << err.message << " at " << err.line << ':' << err.column << std::endl;
std::cout << girl.name() << std::endl;

...
```

Compile your program as usual (no additional library is required). In the example above, the output would be:
Compile your program as usual. In the example above, the output would be:

```
{"name":"Michelle","age":24,"colors":["yellow"]}
Michelle
```

## Supported options
Expand All @@ -72,7 +74,7 @@ Compile your program as usual (no additional library is required). In the exampl
* **cpp_enable_errors** (top-level) &ndash; Enable (`true`) or disable (`false`) information about parsing errors. The default value is `false`. If enabled, `deserializer` functions will populate the `ErrorInfo` object given as argument. This option can also be enabled by defining the `PROTOGEN_CPP_ENABLE_ERRORS` macro before including the generated C++ header.
* **transient** (field-level) &ndash; Make the field transient (`true`) or not (`false`). Transient fields are not serialized/deserialized. The default value is `false`.
* **custom_parent** (top-level) &ndash; Define a custom parent class for all messages. Use the same syntax as package definition.
* **cpp_use_lists** (top-level) &ndash; Use `std::list` (`true`) instead of `std::vector` (`false`) in repeated fields for C++ outputs. This is useful if your program constantly changes repeated fields (add and/or remove items). This option does not affect `bytes` fields which always use `std::vector`. Do not mix progoten outputs with different values for this option in the same project. The default value is `false`.
* **cpp_use_lists** (top-level) &ndash; Use `std::list` (`true`) instead of `std::vector` (`false`) in repeated fields for C++ outputs. This gives best performance if your program constantly changes repeated fields (add and/or remove items). This option does not affect `bytes` fields which always use `std::vector`. The default value is `false`.

## Features

Expand Down
4 changes: 2 additions & 2 deletions library/cpp/code.txt
Original file line number Diff line number Diff line change
Expand Up @@ -333,8 +333,8 @@ template<> struct traits<std::string>
};
------

--- CODE_REPEATED_TEMPLATE
// proto3 'repeated'
--- CODE_REPEATED_TRAIT
// proto3 'repeated' with $1$ as container
template <typename T> struct traits< $1$<T> >
{
static void clear( $1$<T> &value ) { value.clear(); }
Expand Down
31 changes: 13 additions & 18 deletions library/cpp/cppgen.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ namespace protogen {
#define IS_VALID_TYPE(x) ( (x) >= protogen::TYPE_DOUBLE && (x) <= protogen::TYPE_MESSAGE )
#define IS_NUMERIC_TYPE(x) ( (x) >= protogen::TYPE_DOUBLE && (x) <= protogen::TYPE_SFIXED64 )

#ifdef _WIN32
#define SNPRINTF snprintf_
#else
#define SNPRINTF snprintf
#endif

struct GeneratorContext
{
Expand Down Expand Up @@ -220,13 +225,9 @@ static void generateVariable( GeneratorContext &ctx, const Field &field )
{
std::string storage = fieldStorage(field);

char number[10];
snprintf(number, sizeof(number), "%d", field.index);
number[9] = 0;

ctx.printer(
"static const int $3$_NO = $4$;\n"
"$1$ $2$;\n", fieldNativeType(field, ctx.cpp_use_lists), storage, toUpper(storage), number);
"$1$ $2$;\n", fieldNativeType(field, ctx.cpp_use_lists), storage, toUpper(storage), std::to_string(field.index));
}


Expand Down Expand Up @@ -543,9 +544,7 @@ static void generateMessage( GeneratorContext &ctx, const Message &message, bool
std::string name;
if (ctx.number_names)
{
char temp[12] = {0};
snprintf(temp, sizeof(temp) - 1, "%d", fi->index);
name = temp;
name = std::to_string(fi->index);
}
else
name = fieldStorage(*fi);
Expand Down Expand Up @@ -702,10 +701,10 @@ static void sort( GeneratorContext &ctx )
static void generateModel( GeneratorContext &ctx )
{
char version[12] = { 0 };
snprintf(version, sizeof(version) - 1, "%02X%02X%02X",
SNPRINTF(version, sizeof(version) - 1, "%02X%02X%02X",
(int) PROTOGEN_MAJOR, (int) PROTOGEN_MINOR, (int) PROTOGEN_PATCH);
ctx.versionNo = version;
snprintf(version, sizeof(version) - 1, "%d_%d_%d",
SNPRINTF(version, sizeof(version) - 1, "%d_%d_%d",
(int) PROTOGEN_MAJOR, (int) PROTOGEN_MINOR, (int) PROTOGEN_PATCH);
ctx.version = version;

Expand All @@ -725,9 +724,6 @@ static void generateModel( GeneratorContext &ctx )
if (ctx.cpp_enable_errors)
ctx.printer("#define PROTOGEN_CPP_ENABLE_ERRORS // enable parsing error information\n");

if (ctx.cpp_use_lists)
ctx.printer("\n#include <list>\n");

ctx.printer(
"\n#include <string>\n"
"#include <cstring>\n"
Expand All @@ -736,6 +732,7 @@ static void generateModel( GeneratorContext &ctx )
"#include <sstream>\n"
"#include <iostream>\n"
"#include <vector>\n"
"#include <list>\n"
"#include <cstdlib>\n"
"#include <locale.h>\n"
"#include <stdexcept>\n\n");
Expand All @@ -749,13 +746,11 @@ static void generateModel( GeneratorContext &ctx )
"\n#ifndef PROTOGEN_BASE_$1$\n"
"#define PROTOGEN_BASE_$1$\n", ctx.version);

const char *repeatedType = "std::vector";
if (ctx.cpp_use_lists) repeatedType = "std::list";

ctx.printer.output() << CODE_BLOCK_2;
ctx.printer(CODE_REPEATED_TEMPLATE, repeatedType);
ctx.printer(CODE_REPEATED_TRAIT, "std::vector");
ctx.printer(CODE_REPEATED_TRAIT, "std::list");
ctx.printer.output() << CODE_BLOCK_3;
ctx.printer(CODE_REPEATED_FIELD, repeatedType);
ctx.printer(CODE_REPEATED_FIELD);
if (ctx.cpp_enable_parent)
ctx.printer(CODE_PARENT_CLASS);
if (ctx.obfuscate_strings)
Expand Down

0 comments on commit b8e4bcb

Please sign in to comment.