Skip to content
This repository was archived by the owner on Jul 25, 2022. It is now read-only.

Latest commit

 

History

History
144 lines (119 loc) · 3.7 KB

File metadata and controls

144 lines (119 loc) · 3.7 KB

Hacking

Useful links

Helper scripts (bin/)

Several helper scripts are available for use. You should run these scripts under the root folder (i.e. bin/foo), not under the bin folder (i.e. cd bin; ./foo). These scripts only run under a *nix system (GNU/Linux, Apple macOS, and possibly some BSD), not Microsoft Windows.

  • bin/build: Builds the project. The main binary is located at code due to restrictions of the online judge platform.
  • bin/build-node: Builds the Node.js binding. The binary is at build/Release/ticket.node.
  • bin/clean: Cleans build artifacts and data files.
  • bin/command-parser.js: Reads commands.yml and generates several autogenerated files. Running this script requires Node.js to be installed. It should be invoked by running node bin/command-parser from the root directory. The files are:
    • src/node.cpp, the Node.js binding
    • src/parser.cpp, the command parser implementation
    • src/parser.h, the command parser interface
    • src/run.h, the command runner interface
    • index.d.ts, TypeScript declarations for the Node bindings
  • bin/configure-node: Configures the project for the Node bindings build
  • bin/get-testdata: Downloads test points from the SJTU cloud drive. Only intended for members of the ACM class of SJTU. Does not work on macOS.
  • bin/run-test: Runs a test in the test points downloaded by bin/get-testdata.
  • bin/run-unit-test: Runs a specific unit test. Used by CTest.

Internals

Using model classes (aka Create, Read, Update, Delete)

// Adds a user.
User u;
u.username = "Hello";
u.save();
// remember to insert into the indexes.
User::ixUsername.insert(u);

// finds a user.
User u1 = User::get(/* id */ 0);
Optional<User> yyu = User::ixUsername.findOne(
  /* username */ "yyu");
Optional<int> yyuId = User::ixUsername.findOneId("yyu");
Vector<User> yyus = User::ixUsername.findMany("yyu");
// how to use Optionals:
if (yyu) {
  std::cout << yyu->email.str() << std::endl;
} else {
  // there isn't a user named "yyu".
}

// updates a user.
u1.email = "hello@example.com";
u1.update();

// removes a user.
u.destroy();
// indexes need to be manually maintained.
User::ixUsername.remove(u);

// removes all users.
User::truncate();
User::ixUsername.truncate();

Using file metadata objects

Metadata is a small block of storage at the beginning of a file. You can use this block to store a chunk of constant-sized data.

For example, if we have:

struct LastEntry {
  int id;
};
using LogEntry = file::Managed<LogEntryBase, LastEntry>;

then we could use:

// get metadata
LastEntry metadata = LogEntry::file.getMeta();

// set metadata
LastEntry metadata { entry.id() };
LogEntry::file.setMeta(metadata);

Using variants

Variant<int, bool> v1 = 1;
bool isInt = v1.is<int>(); // true
bool isBool = v1.is<bool>(); // false
int *ptr = v1.get<int>(); // points to 1
bool *ptr1 = v1.get<bool>(); // nullptr
v1 = true;
int ix = v1.index(); // 1

Using results

Result<int, Exception> res = 1926;
Result<int, Exception> res2 = Exception("error");
if (auto err = res.error()) {
  std::cout << err->what() << std::endl;
}
std::cout << res.result() << std::endl;

Using optionals

Optional<int> opt = 1;
// i.e. opt.operator bool()
TICKET_ASSERT(opt);
opt = unit;
TICKET_ASSERT(!opt);
opt = 1;
std::cout << *opt << std::endl;