<commit_before>
#include <sstream> // stringstream
#include <iostream> // cout
#include <vector> // vector type
#include <map> // map type
#include <string> // string type
#include <typeinfo> // typeid
#include <cstring> // strchr, strncmp
#include <cstdlib> // exit
using std::cout;
using std::map;
using std::vector;
using std::stringstream;
using std::string;

/// Simple command-line parser modeled after the ns3 CommandLine class. 
///
/// Add values to initialize by calling .addValue( string name, T &value ) 
/// where T is the type of value. This will configure the parser set the variable
/// "value" when it encounters "name". 
/// For example: ```opts.addValue( "--count", &count ); opts.parse(argc, argv); ``` 
/// will set the variable count to 4 when parsing "--count=4" or "--count 4". 
///
/// The methods "addValue" and "addChoice" return the parser, so they can be strung
/// together. See the example program below.
/// 
/// The "parse ( int argc, char *argv[] )" method returns true if it
/// parses with no errors. It is an error to encounter an unknown option.
/// 
/// Parsing storts from argv[0], so if you're calling parse directly from main,
/// you'll probably want to skip the first argv (which contains the program name.)
/// Eg: args.parse(argc-1, argv+1)
/// 
/// Parsing stops when a double dash (--) is encountered and the argc and argv members 
/// are set where parsing left off.

#ifdef _example_use_ // this is a documenting example
#include "commandline.h"

using std::stringstream;
using std::cout;

int main ( int argc, char** argv ) {

  int x=1, y=2;  // declare two ints with default values
  float pi=3.14; // declare float with default value
  string str="default";    // declare string with default value

  opts_t opts; // declare an opts_t instance and configure it.
  opts
    .addValue("x", "Help string for x value", &x) // add option for int x
    .addValue("y", "Help string for y value", &y) // add option for int y
    .addChoice( 1 )  // add choices for y (the last option)
    .addChoice( 2 )
    .addChoice( 3 )
    .addValue("pi", "Help string for pi value", &pi)
    .addValue("string", "Help string for string value", &str);

  cout << "Usage:\n" << argv[0] << " [options]\n" 
       << opts.usage() << "\n\n";

  cout << "Parsing arguments to " << argv[0] << "\n\n";
  // Note that parsing starts from argv[0], so call parse on arc-1 and argv+1.
  if ( ! opts.parse ( argc-1, argv+1 ) ) {
    cout << "error parsing\n";
    cout << opts.usage();
  }
  
  cout << "\nDumping values before exit:\n" << opts.dump();

};
#endif //  example

// todo:  long and short

/// output the name of a variable's type.
template < class T >
string typestr ( T v ) {
  string t = typeid( v ).name();
  return typeid( int ).name() == t?      "int":
    typeid( unsigned ).name() == t?      "unsigned":
    typeid( unsigned long ).name() == t? "unsigned long":
    typeid( long ).name() == t?          "long":
    typeid( double ).name() == t?        "double":
    typeid( float ).name() == t?         "float":
    typeid( string ).name() == t?        "string":
    typeid( char* ).name() == t?         "char*":
    typeid( char** ).name() == t?        "char**":
    t;
};


class opts_t {

 public:
  // argc and argv are set to point to the parameters after the "--"
  int argc;
  char **argv;
  
 opts_t(): argc(-1), argv((char**)0) {};

  template < class T > 
    opts_t &addValue ( string name, string help, T* v ) {
    // check for duplicates
    for ( unsigned i = 0; i < opts.size(); i++) {
      if ( name == opts[i]->name ) { 
	cout << "Error: duplicate " << name << "\n"; 
	exit ( 1 );
      }
    }
    opt_basictype_t < T > *o = new opt_basictype_t < T > ( name, help, v );
    opts.push_back ( o ); 
    return *this;
  };

  template < class T >
    opts_t &addChoice ( T c ) { 
    unsigned last = opts.size() - 1;
    if ( last < 0 ) { 
      cout << "Error: no option to add a choice to.";
      exit (1); 
    }
    opt_basictype_t < T > *opt = 
      dynamic_cast < opt_basictype_t<T>* > ( opts[ last ] );
    if ( ! opt ) {<commit_msg>Move initialization inside constructor.<commit_after>
#include <sstream> // stringstream
#include <iostream> // cout
#include <vector> // vector type
#include <map> // map type
#include <string> // string type
#include <typeinfo> // typeid
#include <cstring> // strchr, strncmp
#include <cstdlib> // exit
using std::cout;
using std::map;
using std::vector;
using std::stringstream;
using std::string;

/// Simple command-line parser modeled after the ns3 CommandLine class. 
///
/// Add values to initialize by calling .addValue( string name, T &value ) 
/// where T is the type of value. This will configure the parser set the variable
/// "value" when it encounters "name". 
/// For example: ```opts.addValue( "--count", &count ); opts.parse(argc, argv); ``` 
/// will set the variable count to 4 when parsing "--count=4" or "--count 4". 
///
/// The methods "addValue" and "addChoice" return the parser, so they can be strung
/// together. See the example program below.
/// 
/// The "parse ( int argc, char *argv[] )" method returns true if it
/// parses with no errors. It is an error to encounter an unknown option.
/// 
/// Parsing storts from argv[0], so if you're calling parse directly from main,
/// you'll probably want to skip the first argv (which contains the program name.)
/// Eg: args.parse(argc-1, argv+1)
/// 
/// Parsing stops when a double dash (--) is encountered and the argc and argv members 
/// are set where parsing left off.

#ifdef _example_use_ // this is a documenting example
#include "commandline.h"

using std::stringstream;
using std::cout;

int main ( int argc, char** argv ) {

  int x=1, y=2;  // declare two ints with default values
  float pi=3.14; // declare float with default value
  string str="default";    // declare string with default value

  opts_t opts; // declare an opts_t instance and configure it.
  opts
    .addValue("x", "Help string for x value", &x) // add option for int x
    .addValue("y", "Help string for y value", &y) // add option for int y
    .addChoice( 1 )  // add choices for y (the last option)
    .addChoice( 2 )
    .addChoice( 3 )
    .addValue("pi", "Help string for pi value", &pi)
    .addValue("string", "Help string for string value", &str);

  cout << "Usage:\n" << argv[0] << " [options]\n" 
       << opts.usage() << "\n\n";

  cout << "Parsing arguments to " << argv[0] << "\n\n";
  // Note that parsing starts from argv[0], so call parse on arc-1 and argv+1.
  if ( ! opts.parse ( argc-1, argv+1 ) ) {
    cout << "error parsing\n";
    cout << opts.usage();
  }
  
  cout << "\nDumping values before exit:\n" << opts.dump();

};
#endif //  example

// todo:  long and short

/// output the name of a variable's type.
template < class T >
string typestr ( T v ) {
  string t = typeid( v ).name();
  return typeid( int ).name() == t?      "int":
    typeid( unsigned ).name() == t?      "unsigned":
    typeid( unsigned long ).name() == t? "unsigned long":
    typeid( long ).name() == t?          "long":
    typeid( double ).name() == t?        "double":
    typeid( float ).name() == t?         "float":
    typeid( string ).name() == t?        "string":
    typeid( char* ).name() == t?         "char*":
    typeid( char** ).name() == t?        "char**":
    t;
};


class opts_t {

 public:
  // argc and argv are set to point to the parameters after the "--"
  int argc;
  char **argv;
  
  opts_t() {
    this->argc = -1; 
    this->argv = (char **) 0;
  };

  template < class T > 
    opts_t &addValue ( string name, string help, T* v ) {
    // check for duplicates
    for ( unsigned i = 0; i < opts.size(); i++) {
      if ( name == opts[i]->name ) { 
	cout << "Error: duplicate " << name << "\n"; 
	exit ( 1 );
      }
    }
    opt_basictype_t < T > *o = new opt_basictype_t < T > ( name, help, v );
    opts.push_back ( o ); 
    return *this;
  };

  template < class T >
    opts_t &addChoice ( T c ) { 
    unsigned last = opts.size() - 1;
    if ( last < 0 ) { 
      cout << "Error: no option to add a choice to.";
      exit (1); 
    }
    opt_basictype_t < T > *opt = 
      dynamic_cast < opt_basictype_t<T>* > ( opts[ last ] );
    if ( ! opt ) {
{'fraction_non_alphanumeric': 0.16087640721462293, 'fraction_numerical': 0.0070209417746035585, 'mean_word_length': 2.5859375, 'pattern_counts': {'":': 18, '<': 103, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6834379', 'n_tokens_mistral': 2717, 'n_tokens_neox': 2635, 'n_words': 1020}