<commit_before>// librarian.h

#ifndef LIBRARIAN_H
#define LIBRARIAN_H

#include "library.h"
#include "alist.h"
#include "syntax.h"
#include "tmpstream.h"
#include <map>

class Log;

template <class T>
class Librarian
{
  // Types.
private:
  typedef T& (*constructor) (const AttributeList&);
  typedef map<string, constructor, less<string>/**/> map_type;
  // Content.
private:
  static struct Content
  {
    Library lib;
    map_type constructors;
    int count;
    Content (const char *const name, derive_fun derive, 
	     const char *const description)
      : lib (name, derive, description),
	constructors (),
	count (1)
    { }
  } *content;

  // Functions.
public:
  static T& create (const AttributeList& al)
  {
    assert (al.check ("type"));
    const string name = al.name ("type");
    assert (library ().check (name));
    TmpStream dummy_stream;
    assert (library ().syntax (name).check (al, dummy_stream ()));
    return (content->constructors)[name] (al);
  }
  static void add_type (const string& name, AttributeList& al,
			const Syntax& syntax,
			constructor cons)
  {
    library ().add (name, al, syntax);
    content->constructors.insert(map_type::value_type (name, cons));
  }
  static void derive_type (const string& name, AttributeList& al,
			   const string& super)
  {
    add_type (name, al, library ().syntax (super),
	      (content->constructors)[super]);
  }
  static Library& library ()
  {
    assert (content);
    return content->lib;
  }

  // Create and Destroy.
public:
  Librarian (const char *const name)
  { 
    if (content)
      content->count++;
    else 
      content = new Content (name, &derive_type, T::description);
  }
  ~Librarian ()
  { 
    if (--content->count == 0)
      {
	delete content;
	content = 0;
      }
  }
};

// This cutie will create a vector of objects from a vector of alists.
template <class T> 
struct map_create
{
  vector<T*>& t;
  map_create (const vector<AttributeList*>& f)
    : t (*new vector<T*> ())
  { 
    for (vector<AttributeList*>::const_iterator i = f.begin ();
	 i != f.end ();
	 i++)
      t.push_back (&Librarian<T>::create (**i));
  }
  operator vector<T*>& ()
  { return t; }
};

template <class T> 
struct map_create_const
{
  vector<const T*>& t;
  map_create_const (const vector<AttributeList*>& f)
    : t (*new vector<const T*> ())
  { 
    for (vector<AttributeList*>::const_iterator i = f.begin ();
	 i != f.end ();
	 i++)
      t.push_back (&Librarian<T>::create (**i));
  }
  operator vector<const T*>& ()
  { return t; }
};

template <class T> 
struct map_construct
{
  vector<T*>& t;
  map_construct (const vector<AttributeList*>& f)
    : t (*new vector<T*> ())
  { 
    for (vector<AttributeList*>::const_iterator i = f.begin ();
	 i != f.end ();
	 i++)
      t.push_back (new T (**i));
  }
  operator vector<T*>& ()
  { return t; }
};

template <class T> 
struct map_construct_const
{
  vector<const T*>& t;
  map_construct_const (const vector<AttributeList*>& f)
    : t (*new vector<const T*> ())
  { 
    for (vector<AttributeList*>::const_iterator i = f.begin ();
	 i != f.end ();
	 i++)
      t.push_back (new T (**i));
  }
  operator vector<const T*>& ()
  { return t; }
};

#endif // LIBRARIAN_H
<commit_msg>Use template functions for VC++.<commit_after>// librarian.h

#ifndef LIBRARIAN_H
#define LIBRARIAN_H

#include "library.h"
#include "alist.h"
#include "syntax.h"
#include "tmpstream.h"
#include <map>

class Log;

template <class T>
class Librarian
{
  // Types.
private:
  typedef T& (*constructor) (const AttributeList&);
  typedef map<string, constructor, less<string>/**/> map_type;
  // Content.
private:
  static struct Content
  {
    Library lib;
    map_type constructors;
    int count;
    Content (const char *const name, derive_fun derive, 
	     const char *const description)
      : lib (name, derive, description),
	constructors (),
	count (1)
    { }
  } *content;

  // Functions.
public:
  static T& create (const AttributeList& al)
  {
    assert (al.check ("type"));
    const string name = al.name ("type");
    assert (library ().check (name));
    TmpStream dummy_stream;
    assert (library ().syntax (name).check (al, dummy_stream ()));
    return (content->constructors)[name] (al);
  }
  static void add_type (const string& name, AttributeList& al,
			const Syntax& syntax,
			constructor cons)
  {
    library ().add (name, al, syntax);
    content->constructors.insert(map_type::value_type (name, cons));
  }
  static void derive_type (const string& name, AttributeList& al,
			   const string& super)
  {
    add_type (name, al, library ().syntax (super),
	      (content->constructors)[super]);
  }
  static Library& library ()
  {
    assert (content);
    return content->lib;
  }

  // Create and Destroy.
public:
  Librarian (const char *const name)
  { 
    if (content)
      content->count++;
    else 
      content = new Content (name, &derive_type, T::description);
  }
  ~Librarian ()
  { 
    if (--content->count == 0)
      {
	delete content;
	content = 0;
      }
  }
};

// This cutie will create a vector of objects from a vector of alists.
#if 1
template <class T> 
vector<T*>&
map_create (const vector<AttributeList*>& f)
{ 
  vector<T*>& t = *new vector<T*> ();
  for (vector<AttributeList*>::const_iterator i = f.begin ();
       i != f.end ();
       i++)
    t.push_back (&Librarian<T>::create (**i));
  return t;
}

template <class T> 
vector<const T*>&
map_create_const (const vector<AttributeList*>& f)
{ 
  vector<const T*>& t = *new vector<const T*> ();
  for (vector<AttributeList*>::const_iterator i = f.begin ();
       i != f.end ();
       i++)
    t.push_back (&Librarian<T>::create (**i));
  return t;
}

template <class T> 
vector<T*>& 
map_construct (const vector<AttributeList*>& f)
{ 
  vector<T*>& t = *new vector<T*> ();
  for (vector<AttributeList*>::const_iterator i = f.begin ();
       i != f.end ();
       i++)
    t.push_back (new T (**i));
  return t;
}

template <class T> 
vector<const T*>&
map_construct_const (const vector<AttributeList*>& f)
{ 
  vector<const T*>& t = *new vector<const T*> ();
  for (vector<AttributeList*>::const_iterator i = f.begin ();
       i != f.end ();
       i++)
    t.push_back (new T (**i));
  return t;
}

#else

template <class T> 
struct map_create
{
  vector<T*>& t;
  map_create (const vector<AttributeList*>& f)
    : t (*new vector<T*> ())
  { 
    for (vector<AttributeList*>::const_iterator i = f.begin ();
	 i != f.end ();
	 i++)
      t.push_back (&Librarian<T>::create (**i));
  }
  operator vector<T*>& ()
  { return t; }
};

template <class T> 
struct map_create_const
{
  vector<const T*>& t;
  map_create_const (const vector<AttributeList*>& f)
    : t (*new vector<const T*> ())
  { 
    for (vector<AttributeList*>::const_iterator i = f.begin ();
	 i != f.end ();
	 i++)
      t.push_back (&Librarian<T>::create (**i));
  }
  operator vector<const T*>& ()
  { return t; }
};

template <class T> 
struct map_construct
{
  vector<T*>& t;
  map_construct (const vector<AttributeList*>& f)
    : t (*new vector<T*> ())
  { 
    for (vector<AttributeList*>::const_iterator i = f.begin ();
	 i != f.end ();
	 i++)
      t.push_back (new T (**i));
  }
  operator vector<T*>& ()
  { return t; }
};

template <class T> 
struct map_construct_const
{
  vector<const T*>& t;
  map_construct_const (const vector<AttributeList*>& f)
    : t (*new vector<const T*> ())
  { 
    for (vector<AttributeList*>::const_iterator i = f.begin ();
	 i != f.end ();
	 i++)
      t.push_back (new T (**i));
  }
  operator vector<const T*>& ()
  { return t; }
};
#endif

#endif // LIBRARIAN_H

{'fraction_non_alphanumeric': 0.1681949174744564, 'fraction_numerical': 0.0009169504846738276, 'mean_word_length': 3.190450054884742, 'pattern_counts': {'":': 0, '<': 89, '<?xml version=': 0, '>': 101, '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': '5120524', 'n_tokens_mistral': 2728, 'n_tokens_neox': 2633, 'n_words': 720}