<commit_before>#include "../TestCase.hpp"

WRD_TEST_START(ChunkTest)
	//	Basic test:
	Chunk chk(4, false);
	//		MemoryHaver:
	T(chk.getLen() == 0)
	T(chk.getSize() == 0)
	T(chk[0] == chk.get(0))
	T( ! chk[1])
	T( ! chk[-1])
	T(chk.isFull())
	T( ! chk.isCapable())
	T( ! chk.has(*(Instance*) NULL))
	//		Allocator:
	T(chk.getBlkSize() == 4)
	T( ! chk.release())
	T(chk.getLen() == 0)
	T(chk.getSize() == 0)
	T( ! chk.getEOB())
	T( ! chk.getHeap())

	//		Chunk:
	class Heap {
	public:
		void new1(Chunk& chk, wcnt cnt) {
			for(int n=0; n < cnt ; n++)
				ptrs.push_back(chk.new1());
		}
		void release(Chunk& chk) {
			chk.release();
			ptrs.clear();
		}
		std::vector<void*> ptrs;
	};
	Heap heap;
	T( ! chk.isFixed())
	heap.new1(chk, 1);
	T(chk.getLen() == 1)
	T(chk.getSize() == Chunk::INIT_SZ)
	T(chk[0])
	T(chk[0] == heap.ptrs[0])
	T( ! chk[-1])
	T(chk.getEOB())
	T(chk.getHeap())

	heap.new1(chk, 1);
	T(chk.getLen() == 2)
	T(chk.getSize() >= chk.getLen())
	T(chk[1])
	T(chk.has(*(Instance*)chk[1]))
	T( chk.getBlkSize() == 4)

	heap.release(chk);
	T(chk.getLen() == 0)
	T(chk.getSize() == 0)
	T( ! chk[0])
	T( ! chk.getHeap())
	T(chk.getBlkSize() == 4)

	T( ! chk.release())
	T(chk.getSize() == 0)
	T( ! chk.getHeap())
	T(chk.getBlkSize() == 4)
	T( ! chk.isFixed())

	T( ! chk.resize(5))
	T(chk.getSize() == Chunk::INIT_SZ)
	T( ! chk.resize(Chunk::INIT_SZ+5))
	T(chk.getSize() == Chunk::INIT_SZ+5)
	T(chk.getLen() == 0)
	T(chk[4] == chk[0])
	T(chk[0] == chk[-1])
	T(chk[-1] == NULL)
	T(chk.getHeap())
	T(chk.getEOB())
	T( ! chk.isFull())
	T(chk.isCapable())

	heap.new1(chk, 10);
	heap.release(chk);
	T( ! chk.getLen())

	heap.new1(chk, 100);
	heap.release(chk);
	T( ! chk.getLen())

	heap.new1(chk, 1000);
	heap.release(chk);
	T( ! chk.getLen())

	heap.new1(chk, 10000);
	heap.release(chk);
	T( ! chk.getLen())

	heap.new1(chk, 100000);
	heap.release(chk);
	T( ! chk.getLen())

	//	fixed chunk:
	Chunk fixed(100);
	T(fixed.getLen() == 0)
	T(fixed.getSize() == 0)
	T(fixed[0] == fixed.get(0))
	T( ! fixed[1])
	T( ! fixed[-1])
	T(fixed.isFull())
	T( ! fixed.isCapable())
	T( ! fixed.has(*(Instance*) NULL))
	//		Allocator:
	T(fixed.getBlkSize() == 100)
	T( ! fixed.release())
	T(fixed.getLen() == 0)
	T(fixed.getSize() == 0)
	T( ! fixed.getEOB())
	T( ! fixed.getHeap())

	T(fixed.isFixed())
	heap.new1(fixed, 1);
	T(fixed.getLen() == 1)
	T(fixed.getSize() >= 1)
	T(fixed[0])
	T(fixed[0] == heap.ptrs[0])
	T( ! fixed[-1])
	T(fixed.getEOB())
	T(fixed.getHeap())

	heap.new1(fixed, 1);
	T(fixed.getLen() == 2)
	T(fixed.getSize() >= fixed.getLen())
	T(fixed[1])
	T(fixed.has(*(Instance*)fixed[1]))
	T(fixed.getBlkSize() == 100)

	heap.release(fixed);
	T(fixed.getLen() == 0)
	T(fixed.getSize() == 0)
	T( ! fixed[0])
	T( ! fixed.getHeap())
	T(fixed.getBlkSize() == 100)

	T( ! fixed.release())
	T(fixed.getSize() == 0)
	T( ! fixed.getHeap())
	T(fixed.getBlkSize() == 100)
	T(fixed.isFixed())

	heap.new1(fixed, 10);
	heap.release(fixed);
	T( ! fixed.getLen())

	heap.new1(fixed, 100);
	heap.release(fixed);
	T( ! fixed.getLen())

	heap.new1(fixed, 1000);
	heap.release(fixed);
	T( ! fixed.getLen())

	heap.new1(fixed, 10000);
	heap.release(fixed);
	T( ! fixed.getLen())

	heap.new1(fixed, 100000);
	heap.release(fixed);
	T( ! fixed.getLen())
	return "";
WRD_TEST_END(ChunkTest)
<commit_msg>- [ut] ChunkTest has defect.<commit_after>#include "../TestCase.hpp"

WRD_TEST_START(ChunkTest)
	//	Basic test:
	Chunk chk(4, false);
	//		MemoryHaver:
	T(chk.getLen() == 0)
	T(chk.getSize() == 0)
	T(chk[0] == chk.get(0))
	T( ! chk[1])
	T( ! chk[-1])
	T(chk.isFull())
	T( ! chk.isCapable())
	T( ! chk.has(*(Instance*) NULL))
	//		Allocator:
	T(chk.getBlkSize() == 4)
	T( ! chk.release())
	T(chk.getLen() == 0)
	T(chk.getSize() == 0)
	T( ! chk.getEOB())
	T( ! chk.getHeap())

	//		Chunk:
	class Heap {
	public:
		wbool new1(Chunk& chk, wcnt cnt) {
			for(int n=0; n < cnt ; n++)
			{
				void* ptr = chk.new1();
				ptrs.push_back(ptr);
				if(!ptr)
					return false;
			}
			return true;
		}
		wbool release(Chunk& chk) {
			if(chk.release()) return false;
			ptrs.clear();
			return true;
		}
		std::vector<void*> ptrs;
	};
	Heap heap;
	T( ! chk.isFixed())
	T(heap.new1(chk, 1))
	T(chk.getLen() == 1)
	T(chk.getSize() == Chunk::INIT_SZ)
	T(chk[0])
	T(chk[0] == heap.ptrs[0])
	T( ! chk[-1])
	T(chk.getEOB())
	T(chk.getHeap())

	T(heap.new1(chk, 1))
	T(chk.getLen() == 2)
	T(chk.getSize() >= chk.getLen())
	T(chk[1])
	T(chk.has(*(Instance*)chk[1]))
	T( chk.getBlkSize() == 4)

	T(heap.release(chk))
	T(chk.getLen() == 0)
	T(chk.getSize() == 0)
	T( ! chk[0])
	T( ! chk.getHeap())
	T(chk.getBlkSize() == 4)

	T( ! chk.release())
	T(chk.getSize() == 0)
	T( ! chk.getHeap())
	T(chk.getBlkSize() == 4)
	T( ! chk.isFixed())

	T( ! chk.resize(5))
	T(chk.getSize() == Chunk::INIT_SZ)
	T( ! chk.resize(Chunk::INIT_SZ+5))
	T(chk.getSize() == Chunk::INIT_SZ+5)
	T(chk.getLen() == 0)
	T(chk[4] == chk[0])
	T(chk[0] == chk[-1])
	T(chk[-1] == NULL)
	T(chk.getHeap())
	T(chk.getEOB())
	T( ! chk.isFull())
	T(chk.isCapable())

	T(heap.new1(chk, 10))
	T(heap.release(chk))
	T( ! chk.getLen())

	T(heap.new1(chk, 100))
	T( ! chk.resize(105))
	T(chk.getLen() == 100)
	T(chk.getSize() > 100)
	T(chk[0])
	T(chk[100] == NULL)
	T(heap.release(chk))
	T( ! chk.getLen())

	T(heap.new1(chk, 1000))
	T(heap.release(chk))
	T( ! chk.getLen())

	T(heap.new1(chk, 10000))
	T(heap.release(chk))
	T( ! chk.getLen())

	T(heap.new1(chk, 100000))
	T(heap.release(chk))
	T( ! chk.getLen())

	//	fixed chunk:
	Chunk fixed(100);
	T(fixed.getLen() == 0)
	T(fixed.getSize() == 0)
	T(fixed[0] == fixed.get(0))
	T( ! fixed[1])
	T( ! fixed[-1])
	T(fixed.isFull())
	T( ! fixed.isCapable())
	T( ! fixed.has(*(Instance*) NULL))
	//		Allocator:
	T(fixed.getBlkSize() == 100)
	T( ! fixed.release())
	T(fixed.getLen() == 0)
	T(fixed.getSize() == 0)
	T( ! fixed.getEOB())
	T( ! fixed.getHeap())

	T(fixed.isFixed())
	T(heap.new1(fixed, 1))
	T(fixed.getLen() == 1)
	T(fixed.getSize() >= 1)
	T(fixed[0])
	T(fixed[0] == heap.ptrs[0])
	T( ! fixed[-1])
	T(fixed.getEOB())
	T(fixed.getHeap())

	T(heap.new1(fixed, 1))
	T(fixed.getLen() == 2)
	T(fixed.getSize() >= fixed.getLen())
	T(fixed[1])
	T(fixed.has(*(Instance*)fixed[1]))
	T(fixed.getBlkSize() == 100)

	T(heap.release(fixed))
	T(fixed.getLen() == 0)
	T(fixed.getSize() == 0)
	T( ! fixed[0])
	T( ! fixed.getHeap())
	T(fixed.getBlkSize() == 100)

	T( ! fixed.release())
	T(fixed.getSize() == 0)
	T( ! fixed.getHeap())
	T(fixed.getBlkSize() == 100)
	T(fixed.isFixed())

	T(heap.new1(fixed, 10))
	T(fixed.getLen() == 10)
	T(heap.release(fixed))
	T(fixed.getLen() == 0)

	T( ! heap.new1(fixed, 100))
	T(fixed.getLen() == 20)
	T(heap.release(fixed))
	T(fixed.getLen() == 0)

	T( ! heap.new1(fixed, 1000))
	T(fixed.getLen() == 20)
	T(heap.release(fixed))
	T(fixed.getLen() == 0)

	T( ! heap.new1(fixed, 10000))
	T(fixed.getLen() == 20)
	T(heap.release(fixed))
	T(fixed.getLen() == 0)

	T( ! heap.new1(fixed, 100000))
	T(fixed.getLen() == 20)
	T(heap.release(fixed))
	T(fixed.getLen() == 0)

	return "";
WRD_TEST_END(ChunkTest)
<|endoftext|>


<commit_before>#pragma once

#include "../TestCase.hpp"

WRD_TESTCASE(ChunkTest, (
	Chunk chk(4, true);

	return "";
))
<commit_msg>+ [ut] add ChunkTest<commit_after>#pragma once

#include "../TestCase.hpp"

WRD_TESTCASE(ChunkTest, (
	//	Basic test:
	Chunk chk(4, true);
	//		MemoryHaver:
	T(chk.getLen() == 0)
	T(chk.getSize() == 1)
	T(chk[0] == chk.get(0))
	T( ! chk[1])
	T( ! chk[-1])
	T( ! chk.isFull())
	T(chk.isCapable())
	T( ! chk.has(*(Instance*) NULL))
	//		Allocator:
	T(chk.getBlkSize() == 4)
	T( ! chk.release())
	T(chk.getLen() == 0)
	T(chk.getSize() == 1)
	T( ! chk.getEOB())
	T( ! chk.getHeap())

	//		Chunk:
	class Heap {
	public:
		static new1(Chunk& chk, wcnt cnt) {
			for(int n=0; n < cnt ; n++)
				ptrs.push_back(chk.new1());
		}
		static del1(Chunk& chk) {
			for(void* e : ptrs)
				chk.del(e, chk.getBlkSize());
			ptrs.clear();
		}
		static std::vector<void*> ptrs;
	};
	T(chk.isFixed())
	Heap::new1(chk, 1);
	T(chk.getLen() == 1)
	T(chk.getSize() >= 1)
	T(chk[0])
	T(chk[0] == Heap::ptrs[0])
	T( ! chk[-1])
	T(chk.getEOB())
	T(chk.getHeap())

	Heap::new1(chk, 1);
	T(chk.getLen() == 2)
	T(chk.getSize() >= chk.getLen())
	T(chk[1])
	T(chk.has(chk[1]))
	T(chk.getBlkSize() == 4)

	Heap::del1(chk)
	T(chk.getLen() == 0)
	T(chk.getSize() >= 2)
	T( ! chk[0])
	T(chk.getHeap())
	T(chk.getBlkSize() == 4)

	T(chk.release())
	T(chk.getSize() == 0)
	T( ! chk.getHeap())
	T(chk.getBlkSize() == 4)
	T(chk.isFixed())

	Heap::new1(chk, 10);
	Heap::del(chk);
	T( ! chk.getLen())

	Heap::new1(chk, 100);
	Heap::del(chk);
	T( ! chk.getLen())

	Heap::new1(chk, 1000);
	Heap::del(chk);
	T( ! chk.getLen())

	Heap::new1(chk, 10000);
	Heap::del(chk);
	T( ! chk.getLen())

	Heap::new1(chk, 100000);
	Heap::del(chk);
	T( ! chk.getLen())

	//	fixed chunk:
	Chunk fixed(100);
	T(fixed.getLen() == 0)
	T(fixed.getSize() == 1)
	T(fixed[0] == fixed.get(0))
	T( ! fixed[1])
	T( ! fixed[-1])
	T( ! fixed.isFull())
	T(fixed.isCapable())
	T( ! fixed.has(*(Instance*) NULL))
	//		Allocator:
	T(fixed.getBlkSize() == 4)
	T( ! fixed.release())
	T(fixed.getLen() == 0)
	T(fixed.getSize() == 1)
	T( ! fixed.getEOB())
	T( ! fixed.getHeap())

	T(fixed.isFixed())
	Heap::new1(fixed, 1);
	T(fixed.getLen() == 1)
	T(fixed.getSize() >= 1)
	T(fixed[0])
	T(fixed[0] == Heap::ptrs[0])
	T( ! fixed[-1])
	T(fixed.getEOB())
	T(fixed.getHeap())

	Heap::new1(fixed, 1);
	T(fixed.getLen() == 2)
	T(fixed.getSize() >= fixed.getLen())
	T(fixed[1])
	T(fixed.has(fixed[1]))
	T(fixed.getBlkSize() == 4)

	Heap::del1(fixed)
	T(fixed.getLen() == 0)
	T(fixed.getSize() >= 2)
	T( ! fixed[0])
	T(fixed.getHeap())
	T(fixed.getBlkSize() == 4)

	T(fixed.release())
	T(fixed.getSize() == 0)
	T( ! fixed.getHeap())
	T(fixed.getBlkSize() == 4)
	T(fixed.isFixed())

	Heap::new1(fixed, 10);
	Heap::del(fixed);
	T( ! fixed.getLen())

	Heap::new1(fixed, 100);
	Heap::del(fixed);
	T( ! fixed.getLen())

	Heap::new1(fixed, 1000);
	Heap::del(fixed);
	T( ! fixed.getLen())

	Heap::new1(fixed, 10000);
	Heap::del(fixed);
	T( ! fixed.getLen())

	Heap::new1(fixed, 100000);
	Heap::del(fixed);
	T( ! fixed.getLen())
	return "";
))
<|endoftext|>


<commit_before>#include <string>
const size_t n_literals = 27;
size_t letterI(const char letter, const bool is_capital) {
	int first_letter_code = static_cast<int>(is_capital ? 'A' : 'a');
	size_t result = static_cast<int>(letter) - first_letter_code + 1;
	return result;
}
struct person {
	char * str;
	unsigned char name_i;
	unsigned char name_length;
        person() : str(nullptr) {
               ;
        }
	size_t i(size_t sort_i) const {
		if (sort_i < name_length) {
			return letterI(str[name_i + sort_i], sort_i == 0);
		}
		else {
			return 0;
		}
	}
	char * getName() {
		char * temp = new char[name_length + 1];
		strncpy(temp, &(str[name_i]), name_length);
		temp[name_length] = '\0';
		return temp;
	} //Boost
        void putStr(std::string const & _str) {
                str = new char[_str.length() + 1];
		strncpy(str, _str, _str.length());
		str[_str.length()] = '\0';
        }
	~person() {
		delete[] str;
	}
};
std::ostream & operator<<(std::ostream & output, person const & _person)
{
	output << _person.str << " ";
	return output;
}
std::istream & operator>>(std::istream & input, person & _person)
{
	input >> _person.str;
	/*input >> _person.name;
	input >> _person.year;*/
	return input;
}
<commit_msg>Update person.hpp<commit_after>#include <string>
#include <cstring>
#include <utility>
#include <algorithm>
#include <unordered_map>
std::unordered_map<std::string, size_t> map;
const size_t n_literals = 27;
size_t letterI(const char letter, const bool is_capital) {
	int first_letter_code = static_cast<int>(is_capital ? 'A' : 'a');
	size_t result = static_cast<int>(letter) - first_letter_code + 1;
	return result;
}
struct person {
	char * str;
	unsigned char name_i;
	unsigned char name_length;
        person() : str(nullptr) {
               ;
        }
        person(person const & _person) : str(_person.str), name_i(_person.name_i), name_length(_person.name_length) {
               ;
        }
        person(person && _person) : str(_person.str), name_i(_person.name_i), name_length(_person.name_length) {
               _person.str = nullptr;
        }
        person & operator=(person && _person) {
	       if (this != &_person) {
                        std::swap(str, _person.str);
                        std::swap(name_i, _person.name_i);
                        std::swap(name_length, _person.name_length);
	       }
	       return *this; //?
        }
	size_t i(size_t sort_i) const {
		/*if (map.find(str) == end()){
			map.insert(str, map.size());
		} else{
			map.find(str).
		}*/
		if (sort_i < name_length) {
			return letterI(str[name_i + sort_i], sort_i == 0);
		}
		else {
			return 0;
		}
	}
	char * getName() const {
		char * temp = new char[name_length + 1];
		strncpy(temp, &(str[name_i]), name_length);
		temp[name_length] = '\0';
		return temp;
	} //Boost
        void putStr(std::string const & _str) {
                str = new char[_str.length() + 1];
		strncpy(str, _str.c_str(), _str.length());
		str[_str.length()] = '\0';
        }
	~person() {
		delete[] str;
	}
};
std::ostream & operator<<(std::ostream & output, person const & _person)
{
	output << _person.str << " ";
	return output;
}
std::istream & operator>>(std::istream & input, person & _person)
{
	std::string str1, str2, str3;
        input >> str1;
	_person.name_i = str1.length() + 1;
	input >> str2;
	_person.name_length = str2.length();
	input >> str3;
        _person.putStr(str1 + " " + str2 + " " + str3);

	return input;
}
<|endoftext|>


<commit_before>/*
 * Copyright 2004-2015 Cray Inc.
 * Other additional copyright holders may be indicated within.
 *
 * The entirety of this work is licensed under the Apache License,
 * Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License.
 *
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <fstream>
#include <iostream>
#include <iterator>
#include <sstream>
#include <sys/stat.h>
#include <sys/types.h>

#include "AstPrintDocs.h"
#include "AstToText.h"
#include "driver.h"
#include "expr.h"
#include "files.h"
#include "mysystem.h"
#include "passes.h"
#include "stmt.h"
#include "symbol.h"
#include "stringutil.h"

#include "docs.h"

static int compareNames(const void* v1, const void* v2) {
  Symbol* s1 = *(Symbol* const *)v1;
  Symbol* s2 = *(Symbol* const *)v2;
  return strcmp(s1->name, s2->name);
}

static int compareClasses(const void *v1, const void* v2) {
  Type *t1 = *(Type* const *)v1;
  Type *t2 = *(Type* const *)v2;
  return strcmp(t1->symbol->name, t2->symbol->name);
}

void docs(void) {

  if (fDocs) {
    // Open the directory to store the docs

    // This is the final location for the output format (e.g. the html files.).
    std::string docsOutputDir;
    if (strlen(fDocsFolder) > 0) {
      docsOutputDir = fDocsFolder;
    } else {
      docsOutputDir = astr(getCwd(), "/docs");
    }

    // Root of the sphinx project and generated rst files. If
    // --docs-save-sphinx is not specified, it will be a temp dir.
    std::string docsTempDir = "";
    std::string docsSphinxDir;
    if (strlen(fDocsSphinxDir) > 0) {
      docsSphinxDir = fDocsSphinxDir;
    } else {
      docsTempDir = makeTempDir("chpldoc-");
      docsSphinxDir = docsTempDir;
    }

    // The location of intermediate rst files.
    std::string docsRstDir;
    if (fDocsTextOnly) {
      // For text-only mode, the output and working location is the same.
      docsRstDir = docsOutputDir;
    } else {
      // For rst mode, the working location is somewhere inside the temp dir.
      docsRstDir = generateSphinxProject(docsSphinxDir);
    }

    // TODO: Check for errors here... (thomasvandoren, 2015-02-25)
    mkdir(docsRstDir.c_str(), S_IWUSR|S_IRUSR|S_IXUSR);
    mkdir(docsOutputDir.c_str(), S_IWUSR|S_IRUSR|S_IXUSR);

    forv_Vec(ModuleSymbol, mod, gModuleSymbols) {
      // TODO: Add flag to compiler to turn on doc dev only output
      if (!mod->hasFlag(FLAG_NO_DOC) && !devOnlyModule(mod)) {
        if (isNotSubmodule(mod)) {
          std::ofstream *file = openFileFromMod(mod, docsRstDir);

          AstPrintDocs *docsVisitor = new AstPrintDocs(file);
          mod->accept(docsVisitor);
          delete docsVisitor;

          // Comment the above three lines and uncomment the following line to
          // get the old category based output (or alphabetical). Note that
          // this will be restored (hopefully soon)... (thomasvandoren, 2015-02-22)
          //
          // printModule(file, mod, 0);

          file->close();
        }
      }
    }

    if (!fDocsTextOnly) {
      generateSphinxOutput(docsSphinxDir, docsOutputDir);
    }

    if (docsTempDir.length() > 0) {
      deleteDir(docsTempDir.c_str());
    }
  }
}

bool isNotSubmodule(ModuleSymbol *mod) {
  return (mod->defPoint == NULL ||
          mod->defPoint->parentSymbol == NULL ||
          mod->defPoint->parentSymbol->name == NULL ||
          strcmp("chpl__Program", mod->defPoint->parentSymbol->name) == 0 ||
          strcmp("_root", mod->defPoint->parentSymbol->name) == 0);
}

void printFields(std::ofstream *file, AggregateType *cl, unsigned int tabs) {
  for (int i = 1; i <= cl->fields.length; i++) {
    if (VarSymbol *var = toVarSymbol(((DefExpr *)cl->fields.get(i))->sym)) {
      var->printDocs(file, tabs);
    }
  }
}

void printClass(std::ofstream *file, AggregateType *cl, unsigned int tabs) {
  if (!cl->symbol->hasFlag(FLAG_NO_DOC) && ! cl->isUnion()) {
    cl->printDocs(file, tabs);

    printFields(file, cl, tabs + 1);

    // In rst mode, add an additional line break after the attributes and
    // before the next directive.
    if (!fDocsTextOnly) {
      *file << std::endl;
    }

    // If alphabetical option passed, alphabetizes the output
    if (fDocsAlphabetize)
      qsort(cl->methods.v, cl->methods.n, sizeof(cl->methods.v[0]),
        compareNames);

    forv_Vec(FnSymbol, fn, cl->methods){
      // We only want to print methods defined within the class under the
      // class header
      if (fn->isPrimaryMethod())
        fn->printDocs(file, tabs + 1);
    }
  }
}

// Returns true if the provided fn is a module initializer, class constructor,
// type constructor, or module copy of a class method.  These functions are
// only printed in developer mode.  Is not applicable to printing class
// functions.
bool devOnlyFunction(FnSymbol *fn) {
  return (fn->hasFlag(FLAG_MODULE_INIT) || fn->hasFlag(FLAG_TYPE_CONSTRUCTOR)
          || fn->hasFlag(FLAG_CONSTRUCTOR) || fn->isPrimaryMethod());
}

// Returns true if the provide module is one of the internal or standard
// modules. It is our opinion that these should only automatically be printed
// out if the user is in developer mode.
bool devOnlyModule(ModuleSymbol *mod) {
  return mod->modTag == MOD_INTERNAL || mod->modTag == MOD_STANDARD;
}

void printModule(std::ofstream *file, ModuleSymbol *mod, unsigned int tabs) {
  if (!mod->hasFlag(FLAG_NO_DOC)) {
    mod->printDocs(file, tabs);

    Vec<VarSymbol*> configs = mod->getTopLevelConfigVars();
    if (fDocsAlphabetize)
      qsort(configs.v, configs.n, sizeof(configs.v[0]), compareNames);
    forv_Vec(VarSymbol, var, configs) {
      var->printDocs(file, tabs + 1);
    }

    Vec<VarSymbol*> variables = mod->getTopLevelVariables();
    if (fDocsAlphabetize)
      qsort(variables.v, variables.n, sizeof(variables.v[0]), compareNames);
    forv_Vec(VarSymbol, var, variables) {
      var->printDocs(file, tabs + 1);
    }
    Vec<FnSymbol*> fns = mod->getTopLevelFunctions(fDocsIncludeExterns);
    // If alphabetical option passed, fDocsAlphabetizes the output
    if (fDocsAlphabetize)
      qsort(fns.v, fns.n, sizeof(fns.v[0]), compareNames);

    forv_Vec(FnSymbol, fn, fns) {
      // TODO: Add flag to compiler to turn on doc dev only output

      // We want methods on classes that are defined at the module level to be
      // printed at the module level
      if (!devOnlyFunction(fn) || fn->isSecondaryMethod()) {
        fn->printDocs(file, tabs + 1);
      }
    }

    Vec<AggregateType*> classes = mod->getTopLevelClasses();
    if (fDocsAlphabetize)
      qsort(classes.v, classes.n, sizeof(classes.v[0]), compareClasses);

    forv_Vec(AggregateType, cl, classes) {
      printClass(file, cl, tabs + 1);
    }

    Vec<ModuleSymbol*> mods = mod->getTopLevelModules();
    if (fDocsAlphabetize)
      qsort(mods.v, mods.n, sizeof(mods.v[0]), compareNames);

    forv_Vec(ModuleSymbol, subMod, mods) {
      // TODO: Add flag to compiler to turn on doc dev only output
      if (!devOnlyModule(subMod)) {
        subMod->addPrefixToName(mod->docsName() + ".");
        printModule(file, subMod, tabs + 1);
      }
    }
  }
}

void createDocsFileFolders(std::string filename) {
  size_t dirCutoff = filename.find("/");
  size_t total = 0;
  while (dirCutoff != std::string::npos) {
    // Creates each subdirectory within the new documentation directory
    dirCutoff += total;
    std::string shorter = filename.substr(dirCutoff+1);
    std::string otherHalf = filename.substr(0, dirCutoff);
    mkdir(otherHalf.c_str(), S_IWUSR|S_IRUSR|S_IXUSR);
    total = dirCutoff + 1;
    dirCutoff = shorter.find("/");
  }
}

/*
 * Create new sphinx project at given location and return path where .rst files
 * should be placed.
 */
std::string generateSphinxProject(std::string dirpath) {
  // Create the output dir under the docs output dir.
  const char * sphinxDir = dirpath.c_str();

  // Ensure output directory exists.
  const char * mkdirCmd = astr("mkdir -p ", sphinxDir);
  mysystem(mkdirCmd, "creating docs output dir");

  // Copy the sphinx template into the output dir.
  const char * sphinxTemplate = astr(CHPL_HOME, "/third-party/chpldoc-venv/chpldoc-sphinx-project/*");
  const char * cmd = astr("cp -r ", sphinxTemplate, " ", sphinxDir, "/");
  mysystem(cmd, "copying chpldoc sphinx template");

  const char * moddir = astr(sphinxDir, "/source/modules");
  return std::string(moddir);
}

/*
 * Invoke sphinx-build using sphinxDir to find conf.py and rst sources, and
 * outputDir for generated html files.
 */
void generateSphinxOutput(std::string sphinxDir, std::string outputDir) {
  // Set the PATH and VIRTUAL_ENV variables in the environment. The values are
  // based on the install path in the third-party/chpldoc-venv/ dir.
  const char * venvDir = astr(
    CHPL_HOME, "/third-party/chpldoc-venv/install/",
    CHPL_TARGET_PLATFORM, "/chpldoc-virtualenv");
  const char * venvBinDir = astr(venvDir, "/bin");
  const char * sphinxBuild = astr(venvBinDir, "/sphinx-build");
  const char * envVars = astr("export PATH=", venvBinDir, ":$PATH && ",
                              "export VIRTUAL_ENV=", venvDir);

  // Run:
  //   $envVars &&
  //     sphinx-build -b html
  //     -d $sphinxDir/build/doctrees -W
  //     $sphinxDir/source $outputDir
  const char * cmdPrefix = astr(envVars, " && ");
  const char * cmd = astr(
    cmdPrefix,
    sphinxBuild, " -b html -d ",
    sphinxDir.c_str(), "/build/doctrees -W ",
    sphinxDir.c_str(), "/source ", outputDir.c_str());
  mysystem(cmd, "building html output from chpldoc sphinx project");
  printf("HTML files are at: %s\n", outputDir.c_str());
}

std::string filenameFromMod(ModuleSymbol *mod, std::string docsWorkDir) {
  std::string filename = mod->filename;

  if (mod->modTag == MOD_INTERNAL) {
    filename = "internal-modules/";
  } else if (mod ->modTag == MOD_STANDARD) {
    filename = "standard-modules/";
  } else {
    size_t location = filename.rfind("/");
    if (location != std::string::npos) {
      filename = filename.substr(0, location + 1);
    } else {
      filename = "";
    }
  }
  filename = docsWorkDir + "/" + filename;
  createDocsFileFolders(filename);

  // Creates files for each top level module.
  if (fDocsTextOnly) {
    filename = filename + mod->name + ".txt";
  } else {
    filename = filename + mod->name + ".rst";
  }

  return filename;
}

std::ofstream* openFileFromMod(ModuleSymbol *mod, std::string docsWorkDir) {
  std::string filename = filenameFromMod(mod, docsWorkDir);
  return new std::ofstream(filename.c_str(), std::ios::out);
}
<commit_msg>Update docs() pass to create output directory with 0777 permissions.<commit_after>/*
 * Copyright 2004-2015 Cray Inc.
 * Other additional copyright holders may be indicated within.
 *
 * The entirety of this work is licensed under the Apache License,
 * Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License.
 *
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <fstream>
#include <iostream>
#include <iterator>
#include <sstream>
#include <sys/stat.h>
#include <sys/types.h>

#include "AstPrintDocs.h"
#include "AstToText.h"
#include "driver.h"
#include "expr.h"
#include "files.h"
#include "mysystem.h"
#include "passes.h"
#include "stmt.h"
#include "symbol.h"
#include "stringutil.h"

#include "docs.h"

static int compareNames(const void* v1, const void* v2) {
  Symbol* s1 = *(Symbol* const *)v1;
  Symbol* s2 = *(Symbol* const *)v2;
  return strcmp(s1->name, s2->name);
}

static int compareClasses(const void *v1, const void* v2) {
  Type *t1 = *(Type* const *)v1;
  Type *t2 = *(Type* const *)v2;
  return strcmp(t1->symbol->name, t2->symbol->name);
}

void docs(void) {

  if (fDocs) {
    // Open the directory to store the docs

    // This is the final location for the output format (e.g. the html files.).
    std::string docsOutputDir;
    if (strlen(fDocsFolder) > 0) {
      docsOutputDir = fDocsFolder;
    } else {
      docsOutputDir = astr(getCwd(), "/docs");
    }

    // Root of the sphinx project and generated rst files. If
    // --docs-save-sphinx is not specified, it will be a temp dir.
    std::string docsTempDir = "";
    std::string docsSphinxDir;
    if (strlen(fDocsSphinxDir) > 0) {
      docsSphinxDir = fDocsSphinxDir;
    } else {
      docsTempDir = makeTempDir("chpldoc-");
      docsSphinxDir = docsTempDir;
    }

    // The location of intermediate rst files.
    std::string docsRstDir;
    if (fDocsTextOnly) {
      // For text-only mode, the output and working location is the same.
      docsRstDir = docsOutputDir;
    } else {
      // For rst mode, the working location is somewhere inside the temp dir.
      docsRstDir = generateSphinxProject(docsSphinxDir);
    }

    // TODO: Check for errors here... (thomasvandoren, 2015-02-25)
    mkdir(docsRstDir.c_str(), 0777);
    mkdir(docsOutputDir.c_str(), 0777);

    forv_Vec(ModuleSymbol, mod, gModuleSymbols) {
      // TODO: Add flag to compiler to turn on doc dev only output
      if (!mod->hasFlag(FLAG_NO_DOC) && !devOnlyModule(mod)) {
        if (isNotSubmodule(mod)) {
          std::ofstream *file = openFileFromMod(mod, docsRstDir);

          AstPrintDocs *docsVisitor = new AstPrintDocs(file);
          mod->accept(docsVisitor);
          delete docsVisitor;

          // Comment the above three lines and uncomment the following line to
          // get the old category based output (or alphabetical). Note that
          // this will be restored (hopefully soon)... (thomasvandoren, 2015-02-22)
          //
          // printModule(file, mod, 0);

          file->close();
        }
      }
    }

    if (!fDocsTextOnly) {
      generateSphinxOutput(docsSphinxDir, docsOutputDir);
    }

    if (docsTempDir.length() > 0) {
      deleteDir(docsTempDir.c_str());
    }
  }
}

bool isNotSubmodule(ModuleSymbol *mod) {
  return (mod->defPoint == NULL ||
          mod->defPoint->parentSymbol == NULL ||
          mod->defPoint->parentSymbol->name == NULL ||
          strcmp("chpl__Program", mod->defPoint->parentSymbol->name) == 0 ||
          strcmp("_root", mod->defPoint->parentSymbol->name) == 0);
}

void printFields(std::ofstream *file, AggregateType *cl, unsigned int tabs) {
  for (int i = 1; i <= cl->fields.length; i++) {
    if (VarSymbol *var = toVarSymbol(((DefExpr *)cl->fields.get(i))->sym)) {
      var->printDocs(file, tabs);
    }
  }
}

void printClass(std::ofstream *file, AggregateType *cl, unsigned int tabs) {
  if (!cl->symbol->hasFlag(FLAG_NO_DOC) && ! cl->isUnion()) {
    cl->printDocs(file, tabs);

    printFields(file, cl, tabs + 1);

    // In rst mode, add an additional line break after the attributes and
    // before the next directive.
    if (!fDocsTextOnly) {
      *file << std::endl;
    }

    // If alphabetical option passed, alphabetizes the output
    if (fDocsAlphabetize)
      qsort(cl->methods.v, cl->methods.n, sizeof(cl->methods.v[0]),
        compareNames);

    forv_Vec(FnSymbol, fn, cl->methods){
      // We only want to print methods defined within the class under the
      // class header
      if (fn->isPrimaryMethod())
        fn->printDocs(file, tabs + 1);
    }
  }
}

// Returns true if the provided fn is a module initializer, class constructor,
// type constructor, or module copy of a class method.  These functions are
// only printed in developer mode.  Is not applicable to printing class
// functions.
bool devOnlyFunction(FnSymbol *fn) {
  return (fn->hasFlag(FLAG_MODULE_INIT) || fn->hasFlag(FLAG_TYPE_CONSTRUCTOR)
          || fn->hasFlag(FLAG_CONSTRUCTOR) || fn->isPrimaryMethod());
}

// Returns true if the provide module is one of the internal or standard
// modules. It is our opinion that these should only automatically be printed
// out if the user is in developer mode.
bool devOnlyModule(ModuleSymbol *mod) {
  return mod->modTag == MOD_INTERNAL || mod->modTag == MOD_STANDARD;
}

void printModule(std::ofstream *file, ModuleSymbol *mod, unsigned int tabs) {
  if (!mod->hasFlag(FLAG_NO_DOC)) {
    mod->printDocs(file, tabs);

    Vec<VarSymbol*> configs = mod->getTopLevelConfigVars();
    if (fDocsAlphabetize)
      qsort(configs.v, configs.n, sizeof(configs.v[0]), compareNames);
    forv_Vec(VarSymbol, var, configs) {
      var->printDocs(file, tabs + 1);
    }

    Vec<VarSymbol*> variables = mod->getTopLevelVariables();
    if (fDocsAlphabetize)
      qsort(variables.v, variables.n, sizeof(variables.v[0]), compareNames);
    forv_Vec(VarSymbol, var, variables) {
      var->printDocs(file, tabs + 1);
    }
    Vec<FnSymbol*> fns = mod->getTopLevelFunctions(fDocsIncludeExterns);
    // If alphabetical option passed, fDocsAlphabetizes the output
    if (fDocsAlphabetize)
      qsort(fns.v, fns.n, sizeof(fns.v[0]), compareNames);

    forv_Vec(FnSymbol, fn, fns) {
      // TODO: Add flag to compiler to turn on doc dev only output

      // We want methods on classes that are defined at the module level to be
      // printed at the module level
      if (!devOnlyFunction(fn) || fn->isSecondaryMethod()) {
        fn->printDocs(file, tabs + 1);
      }
    }

    Vec<AggregateType*> classes = mod->getTopLevelClasses();
    if (fDocsAlphabetize)
      qsort(classes.v, classes.n, sizeof(classes.v[0]), compareClasses);

    forv_Vec(AggregateType, cl, classes) {
      printClass(file, cl, tabs + 1);
    }

    Vec<ModuleSymbol*> mods = mod->getTopLevelModules();
    if (fDocsAlphabetize)
      qsort(mods.v, mods.n, sizeof(mods.v[0]), compareNames);

    forv_Vec(ModuleSymbol, subMod, mods) {
      // TODO: Add flag to compiler to turn on doc dev only output
      if (!devOnlyModule(subMod)) {
        subMod->addPrefixToName(mod->docsName() + ".");
        printModule(file, subMod, tabs + 1);
      }
    }
  }
}

void createDocsFileFolders(std::string filename) {
  size_t dirCutoff = filename.find("/");
  size_t total = 0;
  while (dirCutoff != std::string::npos) {
    // Creates each subdirectory within the new documentation directory
    dirCutoff += total;
    std::string shorter = filename.substr(dirCutoff+1);
    std::string otherHalf = filename.substr(0, dirCutoff);
    mkdir(otherHalf.c_str(), S_IWUSR|S_IRUSR|S_IXUSR);
    total = dirCutoff + 1;
    dirCutoff = shorter.find("/");
  }
}

/*
 * Create new sphinx project at given location and return path where .rst files
 * should be placed.
 */
std::string generateSphinxProject(std::string dirpath) {
  // Create the output dir under the docs output dir.
  const char * sphinxDir = dirpath.c_str();

  // Ensure output directory exists.
  const char * mkdirCmd = astr("mkdir -p ", sphinxDir);
  mysystem(mkdirCmd, "creating docs output dir");

  // Copy the sphinx template into the output dir.
  const char * sphinxTemplate = astr(CHPL_HOME, "/third-party/chpldoc-venv/chpldoc-sphinx-project/*");
  const char * cmd = astr("cp -r ", sphinxTemplate, " ", sphinxDir, "/");
  mysystem(cmd, "copying chpldoc sphinx template");

  const char * moddir = astr(sphinxDir, "/source/modules");
  return std::string(moddir);
}

/*
 * Invoke sphinx-build using sphinxDir to find conf.py and rst sources, and
 * outputDir for generated html files.
 */
void generateSphinxOutput(std::string sphinxDir, std::string outputDir) {
  // Set the PATH and VIRTUAL_ENV variables in the environment. The values are
  // based on the install path in the third-party/chpldoc-venv/ dir.
  const char * venvDir = astr(
    CHPL_HOME, "/third-party/chpldoc-venv/install/",
    CHPL_TARGET_PLATFORM, "/chpldoc-virtualenv");
  const char * venvBinDir = astr(venvDir, "/bin");
  const char * sphinxBuild = astr(venvBinDir, "/sphinx-build");
  const char * envVars = astr("export PATH=", venvBinDir, ":$PATH && ",
                              "export VIRTUAL_ENV=", venvDir);

  // Run:
  //   $envVars &&
  //     sphinx-build -b html
  //     -d $sphinxDir/build/doctrees -W
  //     $sphinxDir/source $outputDir
  const char * cmdPrefix = astr(envVars, " && ");
  const char * cmd = astr(
    cmdPrefix,
    sphinxBuild, " -b html -d ",
    sphinxDir.c_str(), "/build/doctrees -W ",
    sphinxDir.c_str(), "/source ", outputDir.c_str());
  mysystem(cmd, "building html output from chpldoc sphinx project");
  printf("HTML files are at: %s\n", outputDir.c_str());
}

std::string filenameFromMod(ModuleSymbol *mod, std::string docsWorkDir) {
  std::string filename = mod->filename;

  if (mod->modTag == MOD_INTERNAL) {
    filename = "internal-modules/";
  } else if (mod ->modTag == MOD_STANDARD) {
    filename = "standard-modules/";
  } else {
    size_t location = filename.rfind("/");
    if (location != std::string::npos) {
      filename = filename.substr(0, location + 1);
    } else {
      filename = "";
    }
  }
  filename = docsWorkDir + "/" + filename;
  createDocsFileFolders(filename);

  // Creates files for each top level module.
  if (fDocsTextOnly) {
    filename = filename + mod->name + ".txt";
  } else {
    filename = filename + mod->name + ".rst";
  }

  return filename;
}

std::ofstream* openFileFromMod(ModuleSymbol *mod, std::string docsWorkDir) {
  std::string filename = filenameFromMod(mod, docsWorkDir);
  return new std::ofstream(filename.c_str(), std::ios::out);
}
<|endoftext|>


<commit_before>///
/// @file   ptypes.hpp
/// @brief  Convenience functions and typedefs for the non standard
///         __int128_t & __uint128_t integer types.
///
/// Copyright (C) 2014 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#ifndef PTYPES_HPP
#define PTYPES_HPP

#include <stdint.h>

#if defined(HAVE_INT128_T)

namespace primecount {

typedef int128_t maxint_t;

}

#elif defined(HAVE___INT128_T)

#define HAVE_INT128_T

#include <ostream>
#include <string>

namespace primecount {

typedef  __int128_t  maxint_t;
typedef  __int128_t  int128_t;
typedef __uint128_t uint128_t;

inline std::ostream& operator<<(std::ostream& stream, uint128_t n)
{
  std::string str;
  while (n > 0)
  {
    str += '0' + n % 10;
    n /= 10;
  }
  if (str.empty())
    str = "0";
  stream << std::string(str.rbegin(), str.rend());
  return stream;
}

inline std::ostream& operator<<(std::ostream& stream, int128_t n)
{
  std::string str;
  if (n < 0)
  {
    str += '-';
    n = -n;
  }
  while (n > 0)
  {
    str += '0' + n % 10;
    n /= 10;
  }
  if (str.empty())
    str = "0";
  stream << std::string(str.rbegin(), str.rend());
  return stream;
}

} // namespace

#else /* int128_t not supported */

namespace primecount {

typedef int64_t maxint_t;

}

#endif

#endif /* PTYPES_HPP */
<commit_msg>Fix sign bug<commit_after>///
/// @file   ptypes.hpp
/// @brief  Convenience functions and typedefs for the non standard
///         __int128_t & __uint128_t integer types.
///
/// Copyright (C) 2014 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#ifndef PTYPES_HPP
#define PTYPES_HPP

#include <stdint.h>

#if defined(HAVE_INT128_T)

namespace primecount {

typedef int128_t maxint_t;

}

#elif defined(HAVE___INT128_T)

#define HAVE_INT128_T

#include <ostream>
#include <string>

namespace primecount {

typedef __int128_t maxint_t;
typedef __int128_t int128_t;
typedef __uint128_t uint128_t;

inline std::ostream& operator<<(std::ostream& stream, uint128_t n)
{
  std::string str;
  while (n > 0)
  {
    str += '0' + n % 10;
    n /= 10;
  }
  if (str.empty())
    str = "0";
  stream << std::string(str.rbegin(), str.rend());
  return stream;
}

inline std::ostream& operator<<(std::ostream& stream, int128_t n)
{
  std::string str;
  std::string sign = "";
  if (n < 0)
  {
    sign = "-";
    n = -n;
  }
  while (n > 0)
  {
    str += '0' + n % 10;
    n /= 10;
  }
  if (str.empty())
    str = "0";
  stream << sign << std::string(str.rbegin(), str.rend());
  return stream;
}

} // namespace

#else /* int128_t not supported */

namespace primecount {

typedef int64_t maxint_t;

}

#endif

#endif /* PTYPES_HPP */
<|endoftext|>


<commit_before>//
// Copyright (c) 2012 Daniel Lundin
//

#include "medida/reporting/abstract_polling_reporter.h"

#include <atomic>
#include <iostream>
#include <thread>

namespace medida {
    namespace reporting {
        class AbstractPollingReporter::Impl {

        public:
            Impl(AbstractPollingReporter& self);

            ~Impl();

            void Shutdown();

            void Start(Clock::duration period = std::chrono::seconds(5));

        private:
            AbstractPollingReporter& self_;

            std::atomic<bool> running_;

            std::thread thread_;

            void Loop(Clock::duration period);
        };

        AbstractPollingReporter::AbstractPollingReporter() : impl_ {new AbstractPollingReporter::Impl {*this}} { }

        AbstractPollingReporter::~AbstractPollingReporter() { }

        void AbstractPollingReporter::Shutdown() {
            impl_->Shutdown();
        }

        void AbstractPollingReporter::Start(Clock::duration period) {
            impl_->Start(period);
        }

        void AbstractPollingReporter::Run() { }

// === Implementation ===

        AbstractPollingReporter::Impl::Impl(AbstractPollingReporter& self)
            : self_ (self),
              running_ {false} { }

        AbstractPollingReporter::Impl::~Impl() {
            Shutdown();
        }

        void AbstractPollingReporter::Impl::Shutdown() {
            if (running_) {
                running_ = false;
                thread_.join();
            }
        }

        void AbstractPollingReporter::Impl::Start(Clock::duration period) {
            if (!running_) {
                running_ = true;
                thread_ = std::thread(&AbstractPollingReporter::Impl::Loop, this, period);
            }
        }

        void AbstractPollingReporter::Impl::Loop(Clock::duration period) {
            while (running_) {
                std::this_thread::sleep_for(period);
                self_.Run();
            }
        }
    }
}
<commit_msg>Fixed a race-condition in abstract-polling-reporter start and end impl<commit_after>//
// Copyright (c) 2012 Daniel Lundin
//

#include "medida/reporting/abstract_polling_reporter.h"

#include <atomic>
#include <iostream>
#include <thread>

namespace medida {
    namespace reporting {
        class AbstractPollingReporter::Impl {

        public:
            Impl(AbstractPollingReporter& self);

            ~Impl();

            void Shutdown();

            void Start(Clock::duration period = std::chrono::seconds(5));

        private:
            AbstractPollingReporter& self_;

            std::atomic<bool> running_;

            std::thread thread_;

            void Loop(Clock::duration period);
        };

        AbstractPollingReporter::AbstractPollingReporter() : impl_ {new AbstractPollingReporter::Impl {*this}} { }

        AbstractPollingReporter::~AbstractPollingReporter() { }

        void AbstractPollingReporter::Shutdown() {
            impl_->Shutdown();
        }

        void AbstractPollingReporter::Start(Clock::duration period) {
            impl_->Start(period);
        }

        void AbstractPollingReporter::Run() { }

// === Implementation ===

        AbstractPollingReporter::Impl::Impl(AbstractPollingReporter& self)
            : self_ (self),
              running_ {false} { }

        AbstractPollingReporter::Impl::~Impl() {
            Shutdown();
        }

        void AbstractPollingReporter::Impl::Shutdown() {
            bool expected_old_value = true;
            if (running_.compare_exchange_strong(expected_old_value, false)) {
                thread_.join();
            }
        }

        void AbstractPollingReporter::Impl::Start(Clock::duration period) {
            bool expected_old_value = false;
            if (running_.compare_exchange_strong(expected_old_value, true)) {
                thread_ = std::thread(&AbstractPollingReporter::Impl::Loop, this, period);
            }
        }

        void AbstractPollingReporter::Impl::Loop(Clock::duration period) {
            while (running_) {
                std::this_thread::sleep_for(period);
                self_.Run();
            }
        }
    }
}
<|endoftext|>


<commit_before>#ifndef ALEPH_TOPOLOGY_MAXIMAL_CLIQUES_HH__
#define ALEPH_TOPOLOGY_MAXIMAL_CLIQUES_HH__

#include <algorithm>
#include <iterator>
#include <set>
#include <unordered_set>
#include <vector>

#include "math/SparseMatrix.hh"

#include "SimplicialComplex.hh"

namespace aleph
{

namespace topology
{

namespace detail
{

template <class Simplex> auto adjacencyMatrix( const SimplicialComplex<Simplex>& K ) -> math::SparseBinaryMatrix<typename Simplex::VertexType>
{
  using VertexType = typename Simplex::VertexType;
  using Matrix     = math::SparseBinaryMatrix<VertexType>;

  std::set<VertexType> vertices;
  K.vertices( std::inserter( vertices, vertices.begin() );

  Matrix A( vertices.size() );

  // TODO: This ensures that vertex indices in the simplicial complex
  // start at zero. Otherwise, I would first have to look up an index
  // within the set above.
  for( auto itPair = K.range(1); itPair.first != itPair.second; ++itPair.first )
  {
    auto s = *itPair.first;
    auto u = s[0];
    auto v = s[1];

    A.set(u,v);
    A.set(v,u);
  }

  return A;
}

template <class Simplex>
void enumerateKoch( std::unordered_set<typename Simplex::VertexType>& C,
                    std::unordered_set<typename Simplex::VertexType>& I,
                    std::unordered_set<typename Simplex::VertexType>& X,
                    std::vector< std::vector<typename Simplex::VertexType> >& cliques,
                    const SimplicialComplex<Simplex>& K )
{
  (void) K;

  using VertexType = typename Simplex::VertexType;

  if( I.empty() && X.empty() )
  {
    cliques.push_back( std::vector<VertexType>( C.begin(), C.end() ) );
    return;
  }

  // Pivot selection ---------------------------------------------------

  /*
   * NYI
   */

  // Bron--Kerbosch traversal ------------------------------------------

  /*
   * NYI
   */
}

template <class Simplex>
void enumerateBronKerbosch( std::unordered_set<typename Simplex::VertexType>& C,
                            std::unordered_set<typename Simplex::VertexType>& I,
                            std::unordered_set<typename Simplex::VertexType>& X,
                            std::vector< std::vector<typename Simplex::VertexType> >& cliques,
                            const math::SparseBinaryMatrix<typename Simplex::VertexType>& A )
{
  using VertexType = typename Simplex::VertexType;

  if( I.empty() && X.empty() )
  {
    cliques.push_back( std::vector<VertexType>( C.begin(), C.end() ) );
    return;
  }

  for( auto it = I.begin(); it != I.end(); ++it )
  {
    auto element = *it;
    it = I.erase( it );

    auto newC = C;
    newC.insert( element );

    std::unordered_set<VertexType> neighbours;
    A.get( element, std::inserter( neighbours, neighbours.begin() );

    std::unordered_set<VertexType> newI;
    std::unordered_set<VertexType> newX;

    std::set_intersection( I.begin(), I.end(),
                           neighbours.begin(), neighbours.end(),
                           std::inserter( newI,
                                          newI.begin() ) );

    std::set_intersection( X.begin(), X.end(),
                           neighbours.begin(), neighbours.end(),
                           std::inserter( newX,
                                          newX.begin() ) );

    enumerateBronKerbosch( newC,
                           newI,
                           newX,
                           cliques,
                           A );

    X.insert( element );
  }
}

} // namespace detail

/**
  Enumerates all maximal cliques in the given simplicial complex by
  using Koch's modification of the Bron--Kerbosch algorithm for the
  enumeration of cliques.

  Cliques are returned in the form a 2-dimensional vector. For each
  clique, it contains the vertex indices.
*/

template <class Simplex> auto maximalCliquesKoch( const SimplicialComplex<Simplex>& K ) -> std::vector< std::vector<typename Simplex::VertexType> >
{
  using VertexType = typename Simplex::VertexType;

  std::unordered_set<VertexType> C;
  std::unordered_set<VertexType> I;
  std::unordered_set<VertexType> X;

  K.vertices( std::inserter( I, I.begin() ) );

  std::vector< std::vector<VertexType> > cliques;

  detail::enumerateKoch( C, I, X, cliques, K );
  return cliques;
}

template <class Simplex> auto maximalCliquesBronKerbosch( const SimplicialComplex<Simplex>& K ) -> std::vector< std::vector<typename Simplex::VertexType> >
{
  using VertexType = typename Simplex::VertexType;

  std::unordered_set<VertexType> C;
  std::unordered_set<VertexType> I;
  std::unordered_set<VertexType> X;

  K.vertices( std::inserter( I, I.begin() ) );

  std::vector< std::vector<VertexType> > cliques;

  detail::enumerateBronKerbosch( C, I, X, cliques, detail::adjacencyMatrix(K) );
  return cliques;
}

} // namespace topology

} // namespace aleph

#endif
<commit_msg>Fixed clique enumeration implementation problems<commit_after>#ifndef ALEPH_TOPOLOGY_MAXIMAL_CLIQUES_HH__
#define ALEPH_TOPOLOGY_MAXIMAL_CLIQUES_HH__

#include <algorithm>
#include <iterator>
#include <set>
#include <unordered_set>
#include <vector>

#include "math/SparseMatrix.hh"

#include "SimplicialComplex.hh"

namespace aleph
{

namespace topology
{

namespace detail
{

template <class Simplex> auto adjacencyMatrix( const SimplicialComplex<Simplex>& K ) -> math::SparseBinaryMatrix<typename Simplex::VertexType>
{
  using VertexType = typename Simplex::VertexType;
  using Matrix     = math::SparseBinaryMatrix<VertexType>;

  std::set<VertexType> vertices;
  K.vertices( std::inserter( vertices, vertices.begin() ) );

  Matrix A( vertices.size() );

  // TODO: This ensures that vertex indices in the simplicial complex
  // start at zero. Otherwise, I would first have to look up an index
  // within the set above.
  for( auto itPair = K.range(1); itPair.first != itPair.second; ++itPair.first )
  {
    auto s = *itPair.first;
    auto u = s[0];
    auto v = s[1];

    A.set(u,v);
    A.set(v,u);
  }

  return A;
}

template <class Simplex>
void enumerateKoch( std::unordered_set<typename Simplex::VertexType>& C,
                    std::unordered_set<typename Simplex::VertexType>& I,
                    std::unordered_set<typename Simplex::VertexType>& X,
                    std::vector< std::vector<typename Simplex::VertexType> >& cliques,
                    const SimplicialComplex<Simplex>& K )
{
  (void) K;

  using VertexType = typename Simplex::VertexType;

  if( I.empty() && X.empty() )
  {
    cliques.push_back( std::vector<VertexType>( C.begin(), C.end() ) );
    return;
  }

  // Pivot selection ---------------------------------------------------

  /*
   * NYI
   */

  // Bron--Kerbosch traversal ------------------------------------------

  /*
   * NYI
   */
}

template <class Simplex>
void enumerateBronKerbosch( std::unordered_set<typename Simplex::VertexType>& C,
                            std::unordered_set<typename Simplex::VertexType>& I,
                            std::unordered_set<typename Simplex::VertexType>& X,
                            std::vector< std::vector<typename Simplex::VertexType> >& cliques,
                            const math::SparseBinaryMatrix<typename Simplex::VertexType>& A )
{
  using VertexType = typename Simplex::VertexType;

  if( I.empty() && X.empty() )
  {
    cliques.push_back( std::vector<VertexType>( C.begin(), C.end() ) );
    return;
  }

  for( auto it = I.begin(); it != I.end(); ++it )
  {
    auto element = *it;
    it = I.erase( it );

    auto newC = C;
    newC.insert( element );

    std::unordered_set<VertexType> neighbours;
    A.get( element, std::inserter( neighbours, neighbours.begin() ) );

    std::unordered_set<VertexType> newI;
    std::unordered_set<VertexType> newX;

    std::set_intersection( I.begin(), I.end(),
                           neighbours.begin(), neighbours.end(),
                           std::inserter( newI,
                                          newI.begin() ) );

    std::set_intersection( X.begin(), X.end(),
                           neighbours.begin(), neighbours.end(),
                           std::inserter( newX,
                                          newX.begin() ) );

    enumerateBronKerbosch( newC,
                           newI,
                           newX,
                           cliques,
                           A );

    X.insert( element );
  }
}

} // namespace detail

/**
  Enumerates all maximal cliques in the given simplicial complex by
  using Koch's modification of the Bron--Kerbosch algorithm for the
  enumeration of cliques.

  Cliques are returned in the form a 2-dimensional vector. For each
  clique, it contains the vertex indices.
*/

template <class Simplex> auto maximalCliquesKoch( const SimplicialComplex<Simplex>& K ) -> std::vector< std::vector<typename Simplex::VertexType> >
{
  using VertexType = typename Simplex::VertexType;

  std::unordered_set<VertexType> C;
  std::unordered_set<VertexType> I;
  std::unordered_set<VertexType> X;

  K.vertices( std::inserter( I, I.begin() ) );

  std::vector< std::vector<VertexType> > cliques;

  detail::enumerateKoch( C, I, X, cliques, K );
  return cliques;
}

template <class Simplex> auto maximalCliquesBronKerbosch( const SimplicialComplex<Simplex>& K ) -> std::vector< std::vector<typename Simplex::VertexType> >
{
  using VertexType = typename Simplex::VertexType;

  std::unordered_set<VertexType> C;
  std::unordered_set<VertexType> I;
  std::unordered_set<VertexType> X;

  K.vertices( std::inserter( I, I.begin() ) );

  std::vector< std::vector<VertexType> > cliques;

  detail::enumerateBronKerbosch( C, I, X, cliques, detail::adjacencyMatrix(K) );
  return cliques;
}

} // namespace topology

} // namespace aleph

#endif
<|endoftext|>


<commit_before>/**
 * @file regression_distribution.hpp
 * @author Michael Fox
 *
 * Implementation of conditional Gaussian distribution for HMM regression (HMMR)
 */
#ifndef __MLPACK_METHODS_HMM_DISTRIBUTIONS_REGRESSION_DISTRIBUTION_HPP
#define __MLPACK_METHODS_HMM_DISTRIBUTIONS_REGRESSION_DISTRIBUTION_HPP

#include <mlpack/core.hpp>
#include <mlpack/core/dists/gaussian_distribution.hpp>
#include <mlpack/methods/linear_regression/linear_regression.hpp>

namespace mlpack {
namespace distribution {

/**
 * A class that represents a univariate conditionally Gaussian distribution.
 * Can be used as an emission distribution with the hmm class to implement HMM
 * regression (HMMR) as described in
 * https://www.ima.umn.edu/preprints/January1994/1195.pdf
 * The hmm observations should have the dependent variable in the first row,
 * with the independent variables in the other rows.
 */
class RegressionDistribution
{
 private:
  //! Regression function for representing conditional mean.
  regression::LinearRegression rf;
  //! Error distribution
  GaussianDistribution err;

 public:
  /**
   * Default constructor, which creates a Gaussian with zero dimension.
   */
  RegressionDistribution() { /* nothing to do */ }

  /**
   * Create a Conditional Gaussian distribution with conditional mean function
   * obtained by running RegressionFunction on predictors, responses.
   *
   * @param predictors Matrix of predictors (X).
   * @param responses Vector of responses (y).
   */
  RegressionDistribution(const arma::mat& predictors,
                         const arma::vec& responses) :
      rf(regression::LinearRegression(predictors, responses))
  {
    err = GaussianDistribution(1);
    err.Covariance() = rf.ComputeError(predictors, responses);
  }

  /**
   * Returns a string representation of this object.
   */
  std::string ToString() const;

  // Return regression function
  const regression::LinearRegression& Rf() {return rf;}

  /**
   * Estimate the Gaussian distribution directly from the given observations.
   *
   * @param observations List of observations.
   */
  void Estimate(const arma::mat& observations);

  /**
   * Estimate parameters using provided observation weights
   *
   * @param weights probability that given observation is from distribution
   */
  void Estimate(const arma::mat& observations, const arma::vec& weights);

  /**
  * Evaluate probability density function of given observation
  *
  * @param observation point to evaluate probability at
  */
  double Probability(const arma::vec& observation) const;

  /**
   * Calculate y_i for each data point in points.
   *
   * @param points the data points to calculate with.
   * @param predictions y, will contain calculated values on completion.
   */
  void Predict(const arma::mat& points, arma::vec& predictions) const;

  //! Return the parameters (the b vector).
  const arma::vec& Parameters() const { return rf.Parameters(); }

  //! Return the dimensionality (2) NEED TO FIX THIS
  static const size_t Dimensionality() { return 2; }
};

}; // namespace distribution
}; // namespace mlpack

#endif
<commit_msg>Minor spacing fix.<commit_after>/**
 * @file regression_distribution.hpp
 * @author Michael Fox
 *
 * Implementation of conditional Gaussian distribution for HMM regression (HMMR)
 */
#ifndef __MLPACK_METHODS_HMM_DISTRIBUTIONS_REGRESSION_DISTRIBUTION_HPP
#define __MLPACK_METHODS_HMM_DISTRIBUTIONS_REGRESSION_DISTRIBUTION_HPP

#include <mlpack/core.hpp>
#include <mlpack/core/dists/gaussian_distribution.hpp>
#include <mlpack/methods/linear_regression/linear_regression.hpp>

namespace mlpack {
namespace distribution {

/**
 * A class that represents a univariate conditionally Gaussian distribution.
 * Can be used as an emission distribution with the hmm class to implement HMM
 * regression (HMMR) as described in
 * https://www.ima.umn.edu/preprints/January1994/1195.pdf
 * The hmm observations should have the dependent variable in the first row,
 * with the independent variables in the other rows.
 */
class RegressionDistribution
{
 private:
  //! Regression function for representing conditional mean.
  regression::LinearRegression rf;
  //! Error distribution
  GaussianDistribution err;

 public:
  /**
   * Default constructor, which creates a Gaussian with zero dimension.
   */
  RegressionDistribution() { /* nothing to do */ }

  /**
   * Create a Conditional Gaussian distribution with conditional mean function
   * obtained by running RegressionFunction on predictors, responses.
   *
   * @param predictors Matrix of predictors (X).
   * @param responses Vector of responses (y).
   */
  RegressionDistribution(const arma::mat& predictors,
                         const arma::vec& responses) :
      rf(regression::LinearRegression(predictors, responses))
  {
    err = GaussianDistribution(1);
    err.Covariance() = rf.ComputeError(predictors, responses);
  }

  /**
   * Returns a string representation of this object.
   */
  std::string ToString() const;

  // Return regression function
  const regression::LinearRegression& Rf() { return rf; }

  /**
   * Estimate the Gaussian distribution directly from the given observations.
   *
   * @param observations List of observations.
   */
  void Estimate(const arma::mat& observations);

  /**
   * Estimate parameters using provided observation weights
   *
   * @param weights probability that given observation is from distribution
   */
  void Estimate(const arma::mat& observations, const arma::vec& weights);

  /**
  * Evaluate probability density function of given observation
  *
  * @param observation point to evaluate probability at
  */
  double Probability(const arma::vec& observation) const;

  /**
   * Calculate y_i for each data point in points.
   *
   * @param points the data points to calculate with.
   * @param predictions y, will contain calculated values on completion.
   */
  void Predict(const arma::mat& points, arma::vec& predictions) const;

  //! Return the parameters (the b vector).
  const arma::vec& Parameters() const { return rf.Parameters(); }

  //! Return the dimensionality (2) NEED TO FIX THIS
  static const size_t Dimensionality() { return 2; }
};

}; // namespace distribution
}; // namespace mlpack

#endif
<|endoftext|>


<commit_before>// @(#)root/tree:$Name:  $:$Id: TBranchClones.cxx,v 1.8 2000/12/13 15:13:56 brun Exp $
// Author: Rene Brun   11/02/96

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// A Branch for the case of an array of clone objects                   //                                                                      //
// See TTree.                                                           //                                                                     //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TROOT.h"
#include "TBranchClones.h"
#include "TFile.h"
#include "TTree.h"
#include "TBasket.h"
#include "TClass.h"
#include "TRealData.h"
#include "TDataType.h"
#include "TDataMember.h"
#include "TLeafI.h"

R__EXTERN TTree *gTree;

ClassImp(TBranchClones)

//______________________________________________________________________________
TBranchClones::TBranchClones(): TBranch()
{
//*-*-*-*-*-*Default constructor for BranchClones*-*-*-*-*-*-*-*-*-*
//*-*        ====================================

   fList        = 0;
   fRead        = 0;
   fN           = 0;
   fNdataMax    = 0;
   fBranchCount = 0;
}

//______________________________________________________________________________
TBranchClones::TBranchClones(const char *name, void *pointer, Int_t basketsize, Int_t compress, Int_t splitlevel)
    :TBranch()
{
//*-*-*-*-*-*-*-*-*-*-*-*-*Create a BranchClones*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
//*-*                      =====================
//
   char leaflist[80];
   char branchname[80];
   char branchcount[64];
   SetName(name);
   if (compress == -1 && gTree->GetDirectory()) {
      TFile *bfile = 0;
      if (gTree->GetDirectory()) bfile = gTree->GetDirectory()->GetFile();
      if (bfile) compress = bfile->GetCompressionLevel();
   }
   char *cpointer  = (char*)pointer;
   char **ppointer = (char**)(cpointer);
   fList     = (TClonesArray*)(*ppointer);
   fAddress  = cpointer;
   fRead     = 0;
   fN        = 0;
   fNdataMax = 0;
   TClass *cl = fList->GetClass();
   if (!cl) return;
   gTree->BuildStreamerInfo(cl);

   fClassName = cl->GetName();

//*-*- Create a branch to store the array count
   if (basketsize < 100) basketsize = 100;
   sprintf(leaflist,"%s_/I",name);
   sprintf(branchcount,"%s_",name);
   fBranchCount = new TBranch(branchcount,&fN,leaflist,basketsize);
   fBranchCount->SetBit(kIsClone);
   TLeaf *leafcount = (TLeaf*)fBranchCount->GetListOfLeaves()->UncheckedAt(0);

   fTree       = gTree;
   fDirectory  = fTree->GetDirectory();
   fFileName   = "";

//*-*-  Create the first basket
   TBasket *basket = new TBasket(branchcount,fTree->GetName(),this);
   fBaskets.Add(basket);

//*-*- Loop on all public data members of the class and its base classes
   const char *itype = 0;
   TRealData *rd;
   TIter      next(cl->GetListOfRealData());
   while ((rd = (TRealData *) next())) {
      TDataMember *member = rd->GetDataMember();
      if (!member->IsPersistent()) continue; //do not process members with a ! as the first
                                             // character in the comment field
      if (!member->IsBasic() || member->IsaPointer() ) {
         Warning("BranchClones","Cannot process member:%s",member->GetName());
         continue;
      }
      // forget TObject part if splitlevel = 2
      if (splitlevel > 1 || fList->TestBit(TClonesArray::kForgetBits)
                         || cl->CanIgnoreTObjectStreamer()) {
         if (strcmp(member->GetName(),"fBits")     == 0) continue;
         if (strcmp(member->GetName(),"fUniqueID") == 0) continue;
      }
      TDataType *membertype = member->GetDataType();
      Int_t type = membertype->GetType();
      if (type == 0) {
         Warning("BranchClones","Cannot process member:%s",member->GetName());
         continue;
      }
      if (type == 1)  itype = "B";
      if (type == 11) itype = "b";
      if (type == 3)  itype = "I";
      if (type == 5)  itype = "F";
      if (type == 8)  itype = "D";
      if (type == 13) itype = "i";
      if (type == 2)  itype = "S";
      if (type == 12) itype = "s";
      sprintf(leaflist,"%s[%s]/%s",member->GetName(),branchcount,itype);
      Int_t comp = compress;
      if (type == 5) comp--;
      sprintf(branchname,"%s.%s",name,rd->GetName());
      TBranch *branch  = new TBranch(branchname,this,leaflist,basketsize,comp);
      branch->SetBit(kIsClone);
      TObjArray *leaves = branch->GetListOfLeaves();
      TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(0);
      leaf->SetOffset(rd->GetThisOffset());
      leaf->SetLeafCount(leafcount);
      Int_t arraydim = member->GetArrayDim();
      if (arraydim) {
         Int_t maxindex=1;
         while (arraydim) {
            maxindex *= member->GetMaxIndex(--arraydim);
         }
         leaf->SetLen(maxindex);
      }
      fBranches.Add(branch);
   }
}

//______________________________________________________________________________
TBranchClones::~TBranchClones()
{
//*-*-*-*-*-*Default destructor for a BranchClones*-*-*-*-*-*-*-*-*-*-*-*
//*-*        =====================================

   delete fBranchCount;
   fBranchCount = 0;
   fBranches.Delete();
   fList = 0;
}

//______________________________________________________________________________
void TBranchClones::Browse(TBrowser *b)
{
   fBranches.Browse( b );
}

//______________________________________________________________________________
Int_t TBranchClones::Fill()
{
//*-*-*-*-*Loop on all Branches of this BranchClones to fill Basket buffer*-*
//*-*      ===============================================================

   Int_t i;
   Int_t nbytes = 0;
   Int_t nbranches = fBranches.GetEntriesFast();
   char **ppointer = (char**)(fAddress);
   if (ppointer == 0) return 0;
   fList = (TClonesArray*)(*ppointer);
   fN    = fList->GetEntriesFast();
   fEntries++;

   if (fN > fNdataMax) {
      fNdataMax = fList->GetSize();
      char branchcount[64];
      sprintf(branchcount,"%s_",GetName());
      TLeafI *leafi = (TLeafI*)fBranchCount->GetLeaf(branchcount);
      leafi->SetMaximum(fNdataMax);
      for (i=0;i<nbranches;i++)  {
         TBranch *branch = (TBranch*)fBranches.UncheckedAt(i);
         TObjArray *leaves = branch->GetListOfLeaves();
         TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(0);
         leaf->SetAddress();
      }
   }
   nbytes += fBranchCount->Fill();
   for (i=0;i<nbranches;i++)  {
      TBranch *branch = (TBranch*)fBranches.UncheckedAt(i);
      TObjArray *leaves = branch->GetListOfLeaves();
      TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(0);
      leaf->Import(fList, fN);
      nbytes += branch->Fill();
   }
   return nbytes;
}

//______________________________________________________________________________
Int_t TBranchClones::GetEntry(Int_t entry, Int_t getall)
{
//*-*-*-*-*Read all branches of a BranchClones and return total number of bytes
//*-*      ====================================================================

   if (TestBit(kDoNotProcess) && !getall) return 0;
   Int_t nbytes = fBranchCount->GetEntry(entry);
   TLeaf *leafcount = (TLeaf*)fBranchCount->GetListOfLeaves()->UncheckedAt(0);
   fN = Int_t(leafcount->GetValue());
   if (fN <= 0) {
      if (fList) fList->Clear();
      return 0;
   }
   TBranch *branch;
   Int_t nbranches = fBranches.GetEntriesFast();

     // if fList exists, create clonesarray objects
   if (fList) {
     fList->Clear();
     fList->ExpandCreateFast(fN);
     for (Int_t i=0;i<nbranches;i++)  {
         branch = (TBranch*)fBranches.UncheckedAt(i);
         nbytes += branch->GetEntryExport(entry, getall, fList, fN);
      }
   } else {
      for (Int_t i=0;i<nbranches;i++)  {
         branch = (TBranch*)fBranches.UncheckedAt(i);
         nbytes += branch->GetEntry(entry, getall);
      }
   }
  return nbytes;
}

//______________________________________________________________________________
void TBranchClones::Print(Option_t *option) const
{
//*-*-*-*-*-*-*-*-*-*-*-*Print TBranch parameters*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
//*-*                    ========================

   fBranchCount->Print(option);
   Int_t i;
   Int_t nbranches = fBranches.GetEntriesFast();
   for (i=0;i<nbranches;i++)  {
      TBranch *branch = (TBranch*)fBranches.At(i);
      branch->Print(option);
   }
}

//______________________________________________________________________________
void TBranchClones::Reset(Option_t *option)
{
//*-*-*-*-*-*-*-*Reset a Branch*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
//*-*            ====================
//
//    Existing buffers are deleted
//    Entries, max and min are reset
//

   fEntries        = 0;
   fTotBytes       = 0;
   fZipBytes       = 0;
   Int_t i;
   Int_t nbranches = fBranches.GetEntriesFast();
   for (i=0;i<nbranches;i++)  {
      TBranch *branch = (TBranch*)fBranches.At(i);
      branch->Reset(option);
   }
   fBranchCount->Reset();
}

//______________________________________________________________________________
void TBranchClones::SetAddress(void *add)
{
//*-*-*-*-*-*-*-*Set address of this branch*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
//*-*            ====================
//*-*

   fReadEntry = -1;
   fAddress = (char*)add;
   char **ppointer = (char**)(fAddress);

   // test if the pointer is null
   // in this case create the correct TClonesArray
   if ( (*ppointer)==0 ) {
     *ppointer = (char*) new TClonesArray(fClassName);
     fAddress = (char*)ppointer;
   }

   fList = (TClonesArray*)(*ppointer);
   fBranchCount->SetAddress(&fN);
}

//______________________________________________________________________________
void TBranchClones::SetBasketSize(Int_t buffsize)
{
//*-*-*-*-*-*-*-*Reset basket size for all subbranches of this branchclones
//*-*            ==========================================================
//

   fBasketSize = buffsize;
   Int_t i;
   Int_t nbranches = fBranches.GetEntriesFast();
   for (i=0;i<nbranches;i++)  {
      TBranch *branch = (TBranch*)fBranches[i];
      branch->SetBasketSize(buffsize);
   }
}

//_______________________________________________________________________
void TBranchClones::Streamer(TBuffer &b)
{
//*-*-*-*-*-*-*-*-*Stream a class object*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
//*-*              =========================================
   UInt_t R__s, R__c;
   if (b.IsReading()) {
      b.ReadVersion(&R__s, &R__c);
      TNamed::Streamer(b);
      b >> fCompress;
      b >> fBasketSize;
      b >> fEntryOffsetLen;
      b >> fMaxBaskets;
      b >> fWriteBasket;
      b >> fEntryNumber;
      b >> fEntries;
      b >> fTotBytes;
      b >> fZipBytes;
      b >> fOffset;
      b >> fBranchCount;
      fClassName.Streamer(b);
      fBranches.Streamer(b);
      fTree = gTree;
      TBranch *branch;
      TLeaf *leaf;
      Int_t nbranches = fBranches.GetEntriesFast();
      for (Int_t i=0;i<nbranches;i++)  {
         branch = (TBranch*)fBranches[i];
         branch->SetBit(kIsClone);
         leaf = (TLeaf*)branch->GetListOfLeaves()->UncheckedAt(0);
         leaf->SetOffset(0);
      }
      fRead = 1;
      TClass *cl = gROOT->GetClass((const char*)fClassName);
      if (!cl) {
         Warning("Streamer","Unknow class: %s. Cannot read BranchClones: %s",
            fClassName.Data(),GetName());
         return;
      }
      if (!cl->GetListOfRealData())  cl->BuildRealData();
      char branchname[80];
      TRealData *rd;
      TIter      next(cl->GetListOfRealData());
      while ((rd = (TRealData *) next())) {
         TDataMember *member = rd->GetDataMember();
         if (!member->IsBasic())      continue;
         if (!member->IsPersistent()) continue;
         TDataType *membertype = member->GetDataType();
         if (membertype->GetType() == 0) continue;
         sprintf(branchname,"%s.%s",GetName(),rd->GetName());
         branch  = (TBranch*)fBranches.FindObject(branchname);
         if (!branch) continue;
         TObjArray *leaves = branch->GetListOfLeaves();
         leaf = (TLeaf*)leaves->UncheckedAt(0);
         leaf->SetOffset(rd->GetThisOffset());
      }
      b.CheckByteCount(R__s, R__c, TBranchClones::IsA());
   } else {
      R__c = b.WriteVersion(TBranchClones::IsA(), kTRUE);
      TNamed::Streamer(b);
      b << fCompress;
      b << fBasketSize;
      b << fEntryOffsetLen;
      b << fMaxBaskets;
      b << fWriteBasket;
      b << fEntryNumber;
      b << fEntries;
      b << fTotBytes;
      b << fZipBytes;
      b << fOffset;
      b << fBranchCount;
      fClassName.Streamer(b);
      fBranches.Streamer(b);
      b.SetByteCount(R__c, kTRUE);
   }
}
<commit_msg>Build the StreamerInfo for data members that are classes<commit_after>// @(#)root/tree:$Name:  $:$Id: TBranchClones.cxx,v 1.9 2000/12/18 07:12:58 brun Exp $
// Author: Rene Brun   11/02/96

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// A Branch for the case of an array of clone objects                   //                                                                      //
// See TTree.                                                           //                                                                     //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TROOT.h"
#include "TBranchClones.h"
#include "TFile.h"
#include "TTree.h"
#include "TBasket.h"
#include "TClass.h"
#include "TRealData.h"
#include "TDataType.h"
#include "TDataMember.h"
#include "TLeafI.h"

R__EXTERN TTree *gTree;

ClassImp(TBranchClones)

//______________________________________________________________________________
TBranchClones::TBranchClones(): TBranch()
{
//*-*-*-*-*-*Default constructor for BranchClones*-*-*-*-*-*-*-*-*-*
//*-*        ====================================

   fList        = 0;
   fRead        = 0;
   fN           = 0;
   fNdataMax    = 0;
   fBranchCount = 0;
}

//______________________________________________________________________________
TBranchClones::TBranchClones(const char *name, void *pointer, Int_t basketsize, Int_t compress, Int_t splitlevel)
    :TBranch()
{
//*-*-*-*-*-*-*-*-*-*-*-*-*Create a BranchClones*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
//*-*                      =====================
//
   char leaflist[80];
   char branchname[80];
   char branchcount[64];
   SetName(name);
   if (compress == -1 && gTree->GetDirectory()) {
      TFile *bfile = 0;
      if (gTree->GetDirectory()) bfile = gTree->GetDirectory()->GetFile();
      if (bfile) compress = bfile->GetCompressionLevel();
   }
   char *cpointer  = (char*)pointer;
   char **ppointer = (char**)(cpointer);
   fList     = (TClonesArray*)(*ppointer);
   fAddress  = cpointer;
   fRead     = 0;
   fN        = 0;
   fNdataMax = 0;
   TClass *cl = fList->GetClass();
   if (!cl) return;
   gTree->BuildStreamerInfo(cl);

   fClassName = cl->GetName();

//*-*- Create a branch to store the array count
   if (basketsize < 100) basketsize = 100;
   sprintf(leaflist,"%s_/I",name);
   sprintf(branchcount,"%s_",name);
   fBranchCount = new TBranch(branchcount,&fN,leaflist,basketsize);
   fBranchCount->SetBit(kIsClone);
   TLeaf *leafcount = (TLeaf*)fBranchCount->GetListOfLeaves()->UncheckedAt(0);

   fTree       = gTree;
   fDirectory  = fTree->GetDirectory();
   fFileName   = "";

//*-*-  Create the first basket
   TBasket *basket = new TBasket(branchcount,fTree->GetName(),this);
   fBaskets.Add(basket);

//*-*- Loop on all public data members of the class and its base classes
   const char *itype = 0;
   TRealData *rd;
   TIter      next(cl->GetListOfRealData());
   while ((rd = (TRealData *) next())) {
      TDataMember *member = rd->GetDataMember();
      if (!member->IsPersistent()) continue; //do not process members with a ! as the first
                                             // character in the comment field
      if (!member->IsBasic() || member->IsaPointer() ) {
         Warning("BranchClones","Cannot process member:%s",member->GetName());
         continue;
      }
      // forget TObject part if splitlevel = 2
      if (splitlevel > 1 || fList->TestBit(TClonesArray::kForgetBits)
                         || cl->CanIgnoreTObjectStreamer()) {
         if (strcmp(member->GetName(),"fBits")     == 0) continue;
         if (strcmp(member->GetName(),"fUniqueID") == 0) continue;
      }

      gTree->BuildStreamerInfo(gROOT->GetClass(member->GetFullTypeName()));

      TDataType *membertype = member->GetDataType();
      Int_t type = membertype->GetType();
      if (type == 0) {
         Warning("BranchClones","Cannot process member:%s",member->GetName());
         continue;
      }
      if (type == 1)  itype = "B";
      if (type == 11) itype = "b";
      if (type == 3)  itype = "I";
      if (type == 5)  itype = "F";
      if (type == 8)  itype = "D";
      if (type == 13) itype = "i";
      if (type == 2)  itype = "S";
      if (type == 12) itype = "s";
      sprintf(leaflist,"%s[%s]/%s",member->GetName(),branchcount,itype);
      Int_t comp = compress;
      if (type == 5) comp--;
      sprintf(branchname,"%s.%s",name,rd->GetName());
      TBranch *branch  = new TBranch(branchname,this,leaflist,basketsize,comp);
      branch->SetBit(kIsClone);
      TObjArray *leaves = branch->GetListOfLeaves();
      TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(0);
      leaf->SetOffset(rd->GetThisOffset());
      leaf->SetLeafCount(leafcount);
      Int_t arraydim = member->GetArrayDim();
      if (arraydim) {
         Int_t maxindex=1;
         while (arraydim) {
            maxindex *= member->GetMaxIndex(--arraydim);
         }
         leaf->SetLen(maxindex);
      }
      fBranches.Add(branch);
   }
}

//______________________________________________________________________________
TBranchClones::~TBranchClones()
{
//*-*-*-*-*-*Default destructor for a BranchClones*-*-*-*-*-*-*-*-*-*-*-*
//*-*        =====================================

   delete fBranchCount;
   fBranchCount = 0;
   fBranches.Delete();
   fList = 0;
}

//______________________________________________________________________________
void TBranchClones::Browse(TBrowser *b)
{
   fBranches.Browse( b );
}

//______________________________________________________________________________
Int_t TBranchClones::Fill()
{
//*-*-*-*-*Loop on all Branches of this BranchClones to fill Basket buffer*-*
//*-*      ===============================================================

   Int_t i;
   Int_t nbytes = 0;
   Int_t nbranches = fBranches.GetEntriesFast();
   char **ppointer = (char**)(fAddress);
   if (ppointer == 0) return 0;
   fList = (TClonesArray*)(*ppointer);
   fN    = fList->GetEntriesFast();
   fEntries++;

   if (fN > fNdataMax) {
      fNdataMax = fList->GetSize();
      char branchcount[64];
      sprintf(branchcount,"%s_",GetName());
      TLeafI *leafi = (TLeafI*)fBranchCount->GetLeaf(branchcount);
      leafi->SetMaximum(fNdataMax);
      for (i=0;i<nbranches;i++)  {
         TBranch *branch = (TBranch*)fBranches.UncheckedAt(i);
         TObjArray *leaves = branch->GetListOfLeaves();
         TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(0);
         leaf->SetAddress();
      }
   }
   nbytes += fBranchCount->Fill();
   for (i=0;i<nbranches;i++)  {
      TBranch *branch = (TBranch*)fBranches.UncheckedAt(i);
      TObjArray *leaves = branch->GetListOfLeaves();
      TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(0);
      leaf->Import(fList, fN);
      nbytes += branch->Fill();
   }
   return nbytes;
}

//______________________________________________________________________________
Int_t TBranchClones::GetEntry(Int_t entry, Int_t getall)
{
//*-*-*-*-*Read all branches of a BranchClones and return total number of bytes
//*-*      ====================================================================

   if (TestBit(kDoNotProcess) && !getall) return 0;
   Int_t nbytes = fBranchCount->GetEntry(entry);
   TLeaf *leafcount = (TLeaf*)fBranchCount->GetListOfLeaves()->UncheckedAt(0);
   fN = Int_t(leafcount->GetValue());
   if (fN <= 0) {
      if (fList) fList->Clear();
      return 0;
   }
   TBranch *branch;
   Int_t nbranches = fBranches.GetEntriesFast();

     // if fList exists, create clonesarray objects
   if (fList) {
     fList->Clear();
     fList->ExpandCreateFast(fN);
     for (Int_t i=0;i<nbranches;i++)  {
         branch = (TBranch*)fBranches.UncheckedAt(i);
         nbytes += branch->GetEntryExport(entry, getall, fList, fN);
      }
   } else {
      for (Int_t i=0;i<nbranches;i++)  {
         branch = (TBranch*)fBranches.UncheckedAt(i);
         nbytes += branch->GetEntry(entry, getall);
      }
   }
  return nbytes;
}

//______________________________________________________________________________
void TBranchClones::Print(Option_t *option) const
{
//*-*-*-*-*-*-*-*-*-*-*-*Print TBranch parameters*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
//*-*                    ========================

   fBranchCount->Print(option);
   Int_t i;
   Int_t nbranches = fBranches.GetEntriesFast();
   for (i=0;i<nbranches;i++)  {
      TBranch *branch = (TBranch*)fBranches.At(i);
      branch->Print(option);
   }
}

//______________________________________________________________________________
void TBranchClones::Reset(Option_t *option)
{
//*-*-*-*-*-*-*-*Reset a Branch*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
//*-*            ====================
//
//    Existing buffers are deleted
//    Entries, max and min are reset
//

   fEntries        = 0;
   fTotBytes       = 0;
   fZipBytes       = 0;
   Int_t i;
   Int_t nbranches = fBranches.GetEntriesFast();
   for (i=0;i<nbranches;i++)  {
      TBranch *branch = (TBranch*)fBranches.At(i);
      branch->Reset(option);
   }
   fBranchCount->Reset();
}

//______________________________________________________________________________
void TBranchClones::SetAddress(void *add)
{
//*-*-*-*-*-*-*-*Set address of this branch*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
//*-*            ====================
//*-*

   fReadEntry = -1;
   fAddress = (char*)add;
   char **ppointer = (char**)(fAddress);

   // test if the pointer is null
   // in this case create the correct TClonesArray
   if ( (*ppointer)==0 ) {
     *ppointer = (char*) new TClonesArray(fClassName);
     fAddress = (char*)ppointer;
   }

   fList = (TClonesArray*)(*ppointer);
   fBranchCount->SetAddress(&fN);
}

//______________________________________________________________________________
void TBranchClones::SetBasketSize(Int_t buffsize)
{
//*-*-*-*-*-*-*-*Reset basket size for all subbranches of this branchclones
//*-*            ==========================================================
//

   fBasketSize = buffsize;
   Int_t i;
   Int_t nbranches = fBranches.GetEntriesFast();
   for (i=0;i<nbranches;i++)  {
      TBranch *branch = (TBranch*)fBranches[i];
      branch->SetBasketSize(buffsize);
   }
}

//_______________________________________________________________________
void TBranchClones::Streamer(TBuffer &b)
{
//*-*-*-*-*-*-*-*-*Stream a class object*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
//*-*              =========================================
   UInt_t R__s, R__c;
   if (b.IsReading()) {
      b.ReadVersion(&R__s, &R__c);
      TNamed::Streamer(b);
      b >> fCompress;
      b >> fBasketSize;
      b >> fEntryOffsetLen;
      b >> fMaxBaskets;
      b >> fWriteBasket;
      b >> fEntryNumber;
      b >> fEntries;
      b >> fTotBytes;
      b >> fZipBytes;
      b >> fOffset;
      b >> fBranchCount;
      fClassName.Streamer(b);
      fBranches.Streamer(b);
      fTree = gTree;
      TBranch *branch;
      TLeaf *leaf;
      Int_t nbranches = fBranches.GetEntriesFast();
      for (Int_t i=0;i<nbranches;i++)  {
         branch = (TBranch*)fBranches[i];
         branch->SetBit(kIsClone);
         leaf = (TLeaf*)branch->GetListOfLeaves()->UncheckedAt(0);
         leaf->SetOffset(0);
      }
      fRead = 1;
      TClass *cl = gROOT->GetClass((const char*)fClassName);
      if (!cl) {
         Warning("Streamer","Unknow class: %s. Cannot read BranchClones: %s",
            fClassName.Data(),GetName());
         return;
      }
      if (!cl->GetListOfRealData())  cl->BuildRealData();
      char branchname[80];
      TRealData *rd;
      TIter      next(cl->GetListOfRealData());
      while ((rd = (TRealData *) next())) {
         TDataMember *member = rd->GetDataMember();
         if (!member->IsBasic())      continue;
         if (!member->IsPersistent()) continue;
         TDataType *membertype = member->GetDataType();
         if (membertype->GetType() == 0) continue;
         sprintf(branchname,"%s.%s",GetName(),rd->GetName());
         branch  = (TBranch*)fBranches.FindObject(branchname);
         if (!branch) continue;
         TObjArray *leaves = branch->GetListOfLeaves();
         leaf = (TLeaf*)leaves->UncheckedAt(0);
         leaf->SetOffset(rd->GetThisOffset());
      }
      b.CheckByteCount(R__s, R__c, TBranchClones::IsA());
   } else {
      R__c = b.WriteVersion(TBranchClones::IsA(), kTRUE);
      TNamed::Streamer(b);
      b << fCompress;
      b << fBasketSize;
      b << fEntryOffsetLen;
      b << fMaxBaskets;
      b << fWriteBasket;
      b << fEntryNumber;
      b << fEntries;
      b << fTotBytes;
      b << fZipBytes;
      b << fOffset;
      b << fBranchCount;
      fClassName.Streamer(b);
      fBranches.Streamer(b);
      b.SetByteCount(R__c, kTRUE);
   }
}
<|endoftext|>