<commit_before>// Query binary phrase tables.
// Christian Hardmeier, 16 May 2010

#include <cstdlib>
#include <cstring>
#include <string>
#include <vector>

#include "util.h"
#include "OnDiskWrapper.h"
#include "SourcePhrase.h"

using namespace std;
using namespace OnDiskPt;

void usage();

typedef unsigned int uint;

#define TABLE_LIMIT 20

void Tokenize(OnDiskPt::Phrase &phrase
              , const std::string &token, bool addSourceNonTerm, bool addTargetNonTerm
              , OnDiskPt::OnDiskWrapper &onDiskWrapper)
{

  bool nonTerm = false;
  size_t tokSize = token.size();
  int comStr =token.compare(0, 1, "[");

  if (comStr == 0) {
    comStr = token.compare(tokSize - 1, 1, "]");
    nonTerm = comStr == 0;
  }

  if (nonTerm) {
    // non-term
    size_t splitPos		= token.find_first_of("[", 2);
    string wordStr	= token.substr(0, splitPos);

    if (splitPos == string::npos) {
      // lhs - only 1 word
      Word *word = new Word();
      word->CreateFromString(wordStr, onDiskWrapper.GetVocab());
      phrase.AddWord(word);
    } else {
      // source & target non-terms
      if (addSourceNonTerm) {
        Word *word = new Word();
        word->CreateFromString(wordStr, onDiskWrapper.GetVocab());
        phrase.AddWord(word);
      }

      wordStr = token.substr(splitPos, tokSize - splitPos);
      if (addTargetNonTerm) {
        Word *word = new Word();
        word->CreateFromString(wordStr, onDiskWrapper.GetVocab());
        phrase.AddWord(word);
      }

    }
  } else {
    // term
    Word *word = new Word();
    word->CreateFromString(token, onDiskWrapper.GetVocab());
    phrase.AddWord(word);
  }
}

int main(int argc, char **argv)
{
  int nscores = 5;
  std::string ttable = "";
  bool useAlignments = false;

  for(int i = 1; i < argc; i++) {
    if(!strcmp(argv[i], "-n")) {
      if(i + 1 == argc)
        usage();
      nscores = atoi(argv[++i]);
    } else if(!strcmp(argv[i], "-t")) {
      if(i + 1 == argc)
        usage();
      ttable = argv[++i];
    } else if(!strcmp(argv[i], "-a"))
      useAlignments = true;
    else
      usage();
  }

  if(ttable == "")
    usage();

	OnDiskWrapper onDiskWrapper;
  bool retDb = onDiskWrapper.BeginLoad(ttable);
	CHECK(retDb);

	cerr << "Ready..." << endl;

  std::string line;
  while(getline(std::cin, line)) {
    std::vector<std::string> tokens;
    tokens = Moses::Tokenize(line);

		// create source phrase
    SourcePhrase sourcePhrase;

		for (size_t pos = 0; pos < tokens.size(); ++pos)
		{
		  const string &tok = tokens[pos];

		  if (pos == tokens.size() - 1)
		  { // last position. LHS non-term
			  Tokenize(sourcePhrase, tok, false, true, onDiskWrapper);
			}
			else
			{
			  Tokenize(sourcePhrase, tok, true, true, onDiskWrapper);
			}
		}
		cerr << "size=" << sourcePhrase.GetSize() << endl;

    const PhraseNode *node = &onDiskWrapper.GetRootSourceNode();
		cerr << "node=" << node << endl;
    assert(node);

    for (size_t pos = 0; pos < sourcePhrase.GetSize(); ++pos)
		{
		  const Word &word = sourcePhrase.GetWord(pos);
		  cerr << word << " ";
		  node = node->GetChild(word, onDiskWrapper);
  		cerr << "node=" << node << endl;

		  if (node == NULL)
		  {
		    break;
		  }
		}

    if (node)
    { // source phrase points to something
      const TargetPhraseCollection *coll = node->GetTargetPhraseCollection(TABLE_LIMIT, onDiskWrapper);
      string str = coll->GetDebugStr();
      cout << "Found" << str << endl;
    }
    else
    {
      cout << "Not found" << endl;
    }

    std::cout << '\n';
    std::cout.flush();
  }

  cerr << "Finished." << endl;

}

void usage()
{
  std::cerr << 	"Usage: queryPhraseTable [-n <nscores>] [-a] -t <ttable>\n"
            "-n <nscores>      number of scores in phrase table (default: 5)\n"
            "-a                binary phrase table contains alignments\n"
            "-t <ttable>       phrase table\n";
  exit(1);
}
<commit_msg>Add util for querying on-disk pt<commit_after>// Query binary phrase tables.
// Christian Hardmeier, 16 May 2010

#include <cstdlib>
#include <cstring>
#include <string>
#include <vector>

#include "util.h"
#include "OnDiskWrapper.h"
#include "SourcePhrase.h"

using namespace std;
using namespace OnDiskPt;

void usage();

typedef unsigned int uint;

#define TABLE_LIMIT 20

void Tokenize(OnDiskPt::Phrase &phrase
              , const std::string &token, bool addSourceNonTerm, bool addTargetNonTerm
              , OnDiskPt::OnDiskWrapper &onDiskWrapper)
{

  bool nonTerm = false;
  size_t tokSize = token.size();
  int comStr =token.compare(0, 1, "[");

  if (comStr == 0) {
    comStr = token.compare(tokSize - 1, 1, "]");
    nonTerm = comStr == 0;
  }

  if (nonTerm) {
    // non-term
    size_t splitPos		= token.find_first_of("[", 2);
    string wordStr	= token.substr(0, splitPos);

    if (splitPos == string::npos) {
      // lhs - only 1 word
      Word *word = new Word();
			cerr << "WORD " << *word << " ";
      word->CreateFromString(wordStr, onDiskWrapper.GetVocab());
      cerr << *word << endl;
      phrase.AddWord(word);
    } else {
      // source & target non-terms
      if (addSourceNonTerm) {
        Word *word = new Word();
        word->CreateFromString(wordStr, onDiskWrapper.GetVocab());
        phrase.AddWord(word);
      }

      wordStr = token.substr(splitPos, tokSize - splitPos);
      if (addTargetNonTerm) {
        Word *word = new Word();
        word->CreateFromString(wordStr, onDiskWrapper.GetVocab());
        phrase.AddWord(word);
      }

    }
  } else {
    // term
    Word *word = new Word();
    word->CreateFromString(token, onDiskWrapper.GetVocab());
    phrase.AddWord(word);
  }
}

int main(int argc, char **argv)
{
  int nscores = 5;
  std::string ttable = "";
  bool useAlignments = false;

  for(int i = 1; i < argc; i++) {
    if(!strcmp(argv[i], "-n")) {
      if(i + 1 == argc)
        usage();
      nscores = atoi(argv[++i]);
    } else if(!strcmp(argv[i], "-t")) {
      if(i + 1 == argc)
        usage();
      ttable = argv[++i];
    } else if(!strcmp(argv[i], "-a"))
      useAlignments = true;
    else
      usage();
  }

  if(ttable == "")
    usage();

	OnDiskWrapper onDiskWrapper;
  bool retDb = onDiskWrapper.BeginLoad(ttable);
	CHECK(retDb);

	cerr << "Ready..." << endl;

  std::string line;
  while(getline(std::cin, line)) {
    std::vector<std::string> tokens;
    tokens = Moses::Tokenize(line);

		// create source phrase
    SourcePhrase sourcePhrase;

		for (size_t pos = 0; pos < tokens.size(); ++pos)
		{
		  const string &tok = tokens[pos];

		  if (pos == tokens.size() - 1)
		  { // last position. LHS non-term
			  Tokenize(sourcePhrase, tok, false, true, onDiskWrapper);
			}
			else
			{
			  Tokenize(sourcePhrase, tok, true, true, onDiskWrapper);
			}
		}
		cerr << "size=" << sourcePhrase.GetSize() << endl;

    const PhraseNode *node = &onDiskWrapper.GetRootSourceNode();
		cerr << "node=" << node << endl;
    assert(node);

    for (size_t pos = 0; pos < sourcePhrase.GetSize(); ++pos)
		{
		  const Word &word = sourcePhrase.GetWord(pos);
		  cerr << word << " ";
		  node = node->GetChild(word, onDiskWrapper);
  		cerr << "node=" << node << endl;

		  if (node == NULL)
		  {
		    break;
		  }
		}

    if (node)
    { // source phrase points to something
      const TargetPhraseCollection *coll = node->GetTargetPhraseCollection(TABLE_LIMIT, onDiskWrapper);
      string str = coll->GetDebugStr();
      cout << "Found" << str << endl;
    }
    else
    {
      cout << "Not found" << endl;
    }

    std::cout << '\n';
    std::cout.flush();
  }

  cerr << "Finished." << endl;

}

void usage()
{
  std::cerr << 	"Usage: queryPhraseTable [-n <nscores>] [-a] -t <ttable>\n"
            "-n <nscores>      number of scores in phrase table (default: 5)\n"
            "-a                binary phrase table contains alignments\n"
            "-t <ttable>       phrase table\n";
  exit(1);
}
<|endoftext|>


<commit_before>#pragma once
#include <eos/chain/types.hpp>
#include <eos/types/generated.hpp>

namespace eos { namespace chain {
struct shared_authority {
   shared_authority( chainbase::allocator<char> alloc )
      :accounts(alloc),keys(alloc)
   {}

   shared_authority& operator=(const Authority& a) {
      threshold = a.threshold;
      accounts = decltype(accounts)(a.accounts.begin(), a.accounts.end(), accounts.get_allocator());
      keys = decltype(keys)(a.keys.begin(), a.keys.end(), keys.get_allocator());
      return *this;
   }
   shared_authority& operator=(Authority&& a) {
      threshold = a.threshold;
      accounts.reserve(a.accounts.size());
      for (auto& p : a.accounts)
         accounts.emplace_back(std::move(p));
      keys.reserve(a.keys.size());
      for (auto& p : a.keys)
         keys.emplace_back(std::move(p));
      return *this;
   }

   UInt32                                        threshold = 0;
   shared_vector<types::AccountPermissionWeight> accounts;
   shared_vector<types::KeyPermissionWeight>     keys;
};

inline bool operator< (const types::AccountPermission& a, const types::AccountPermission& b) {
   return std::tie(a.account, a.permission) < std::tie(b.account, b.permission);
}

/**
 * Makes sure all keys are unique and sorted and all account permissions are unique and sorted and that authority can
 * be satisfied
 */
inline bool validate( types::Authority& auth ) {
   const types::KeyPermissionWeight* prev = nullptr;
   decltype(auth.threshold) totalWeight = 0;

   for( const auto& k : auth.keys ) {
      if( !prev ) prev = &k;
      else if( prev->key < k.key ) return false;
      totalWeight += k.weight;
   }
   const types::AccountPermissionWeight* pa = nullptr;
   for( const auto& a : auth.accounts ) {
      if( !pa ) pa = &a;
      else if( pa->permission < a.permission ) return false;
      totalWeight += a.weight;
   }
   return totalWeight >= auth.threshold;
}

} } // namespace eos::chain

FC_REFLECT(eos::chain::shared_authority, (threshold)(accounts)(keys))
<commit_msg>validate(Authority&) -> validate(const Authority&)<commit_after>#pragma once
#include <eos/chain/types.hpp>
#include <eos/types/generated.hpp>

namespace eos { namespace chain {
struct shared_authority {
   shared_authority( chainbase::allocator<char> alloc )
      :accounts(alloc),keys(alloc)
   {}

   shared_authority& operator=(const Authority& a) {
      threshold = a.threshold;
      accounts = decltype(accounts)(a.accounts.begin(), a.accounts.end(), accounts.get_allocator());
      keys = decltype(keys)(a.keys.begin(), a.keys.end(), keys.get_allocator());
      return *this;
   }
   shared_authority& operator=(Authority&& a) {
      threshold = a.threshold;
      accounts.reserve(a.accounts.size());
      for (auto& p : a.accounts)
         accounts.emplace_back(std::move(p));
      keys.reserve(a.keys.size());
      for (auto& p : a.keys)
         keys.emplace_back(std::move(p));
      return *this;
   }

   UInt32                                        threshold = 0;
   shared_vector<types::AccountPermissionWeight> accounts;
   shared_vector<types::KeyPermissionWeight>     keys;
};

inline bool operator< (const types::AccountPermission& a, const types::AccountPermission& b) {
   return std::tie(a.account, a.permission) < std::tie(b.account, b.permission);
}

/**
 * Makes sure all keys are unique and sorted and all account permissions are unique and sorted and that authority can
 * be satisfied
 */
inline bool validate(const types::Authority& auth) {
   const types::KeyPermissionWeight* prev = nullptr;
   decltype(auth.threshold) totalWeight = 0;

   for( const auto& k : auth.keys ) {
      if( !prev ) prev = &k;
      else if( prev->key < k.key ) return false;
      totalWeight += k.weight;
   }
   const types::AccountPermissionWeight* pa = nullptr;
   for( const auto& a : auth.accounts ) {
      if( !pa ) pa = &a;
      else if( pa->permission < a.permission ) return false;
      totalWeight += a.weight;
   }
   return totalWeight >= auth.threshold;
}

} } // namespace eos::chain

FC_REFLECT(eos::chain::shared_authority, (threshold)(accounts)(keys))
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkLinearContourLineInterpolator.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkLinearContourLineInterpolator.h"
#include <vtkObjectFactory.h>

vtkCxxRevisionMacro(vtkLinearContourLineInterpolator, "1.2");
vtkStandardNewMacro(vtkLinearContourLineInterpolator);

//----------------------------------------------------------------------
vtkLinearContourLineInterpolator::vtkLinearContourLineInterpolator()
{
}

//----------------------------------------------------------------------
vtkLinearContourLineInterpolator::~vtkLinearContourLineInterpolator()
{
}

//----------------------------------------------------------------------
int vtkLinearContourLineInterpolator::InterpolateLine( vtkRenderer *vtkNotUsed(ren),
                                                       vtkContourRepresentation *rep,
                                                       int idx1, int idx2 )
{
  return 1;
}

//----------------------------------------------------------------------
void vtkLinearContourLineInterpolator::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
}

<commit_msg>COMP: warnings.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkLinearContourLineInterpolator.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkLinearContourLineInterpolator.h"
#include <vtkObjectFactory.h>

vtkCxxRevisionMacro(vtkLinearContourLineInterpolator, "1.3");
vtkStandardNewMacro(vtkLinearContourLineInterpolator);

//----------------------------------------------------------------------
vtkLinearContourLineInterpolator::vtkLinearContourLineInterpolator()
{
}

//----------------------------------------------------------------------
vtkLinearContourLineInterpolator::~vtkLinearContourLineInterpolator()
{
}

//----------------------------------------------------------------------
int vtkLinearContourLineInterpolator::InterpolateLine( vtkRenderer *vtkNotUsed(ren),
                                                       vtkContourRepresentation *vtkNotUsed(rep),
                                                       int vtkNotUsed(idx1), int vtkNotUsed(idx2) )
{
  return 1;
}

//----------------------------------------------------------------------
void vtkLinearContourLineInterpolator::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
}

<|endoftext|>


<commit_before>#include "Inline/BasicTypes.h"
#include "Inline/Floats.h"
#include "WAST.h"
#include "Lexer.h"
#include "Parse.h"

#include <climits>
#include <cerrno>

// Include the David Gay's dtoa code.
#define IEEE_8087
#define NO_HEX_FP
#define NO_INFNAN_CHECK
#define strtod parseDecimalF64
#define dtoa printDecimalF64

#ifdef _MSC_VER
	#pragma warning(push)
	#pragma warning(disable : 4244 4083 4706 4701 4703)
#elif defined(__GNUC__) && !defined(__clang__)
	#pragma GCC diagnostic push
	#pragma GCC diagnostic ignored "-Wsign-compare"
	#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
	#define Long int
#else
	#pragma GCC diagnostic push
	#pragma GCC diagnostic ignored "-Wsign-compare"
	#define Long int
#endif

#include "../ThirdParty/dtoa.c"

#ifdef _MSC_VER
	#pragma warning(pop)
#else
	#pragma GCC diagnostic pop
	#undef Long
#endif

#undef IEEE_8087
#undef NO_HEX_FP
#undef NO_STRTOD_BIGCOMP
#undef NO_INFNAN_CHECK
#undef strtod
#undef dtoa

using namespace WAST;

// Parses an optional + or - sign and returns true if a - sign was parsed.
// If either a + or - sign is parsed, nextChar is advanced past it.
static bool parseSign(const char*& nextChar)
{
	if(*nextChar == '-') { ++nextChar; return true; }
	else if(*nextChar == '+') { ++nextChar; }
	return false;
}

// Parses an unsigned integer from hexits, starting with "0x", and advancing nextChar past the parsed hexits.
// be called for input that's already been accepted by the lexer as a hexadecimal integer.
static U64 parseHexUnsignedInt(const char*& nextChar,ParseState& state,U64 maxValue)
{
	const char* firstHexit = nextChar;
	assert(nextChar[0] == '0' && (nextChar[1] == 'x' || nextChar[1] == 'X'));
	nextChar += 2;

	U64 result = 0;
	U8 hexit = 0;
	while(tryParseHexit(nextChar,hexit))
	{
		if(result > (maxValue - hexit) / 16)
		{
			parseErrorf(state,firstHexit,"integer literal is too large");
			result = maxValue;
			while(tryParseHexit(nextChar,hexit)) {};
			break;
		}
		assert(result * 16 + hexit >= result);
		result = result * 16 + hexit;
	}
	return result;
}

// Parses an unsigned integer from digits, advancing nextChar past the parsed digits.
// Assumes it will only be called for input that's already been accepted by the lexer as a decimal integer.
static U64 parseDecimalUnsignedInt(const char*& nextChar,ParseState& state,U64 maxValue,const char* context)
{
	U64 result = 0;
	const char* firstDigit = nextChar;
	while(*nextChar >= '0' && *nextChar <= '9')
	{
		const U8 digit = *nextChar - '0';
		++nextChar;

		if(result > U64(maxValue - digit) / 10)
		{
			parseErrorf(state,firstDigit,"%s is too large",context);
			result = maxValue;
			while(*nextChar >= '0' && *nextChar <= '9') { ++nextChar; };
			break;
		}
		assert(result * 10 + digit >= result);
		result = result * 10 + digit;
	};
	return result;
}

// Parses a floating-point NaN, advancing nextChar past the parsed characters.
// Assumes it will only be called for input that's already been accepted by the lexer as a literal NaN.
template<typename Float>
Float parseNaN(const char*& nextChar,ParseState& state)
{
	typedef typename Floats::FloatComponents<Float> FloatComponents;
	FloatComponents resultComponents;
	resultComponents.bits.sign = parseSign(nextChar) ? 1 : 0;
	resultComponents.bits.exponent = FloatComponents::maxExponentBits;

	assert(nextChar[0] == 'n'
	&& nextChar[1] == 'a'
	&& nextChar[2] == 'n');
	nextChar += 3;

	if(*nextChar == ':')
	{
		++nextChar;

		const U64 significandBits = parseHexUnsignedInt(nextChar,state,FloatComponents::maxSignificand);
		resultComponents.bits.significand = typename FloatComponents::Bits(significandBits);
	}
	else
	{
		// If the NaN's significand isn't specified, just set the top bit.
		resultComponents.bits.significand = typename FloatComponents::Bits(1) << (FloatComponents::numSignificandBits-1);
	}

	return resultComponents.value;
}

// Parses a floating-point infinity. Does not advance nextChar.
// Assumes it will only be called for input that's already been accepted by the lexer as a literal infinity.
template<typename Float>
Float parseInfinity(const char* nextChar)
{
	// Floating point infinite is represented by max exponent with a zero significand.
	typedef typename Floats::FloatComponents<Float> FloatComponents;
	FloatComponents resultComponents;
	resultComponents.bits.sign = parseSign(nextChar) ? 1 : 0;
	resultComponents.bits.exponent = FloatComponents::maxExponentBits;
	resultComponents.bits.significand = 0;
	return resultComponents.value;
}

// Parses a decimal floating point literal, advancing nextChar past the parsed characters.
// Assumes it will only be called for input that's already been accepted by the lexer as a decimal float literal.
template<typename Float>
Float parseDecimalFloat(const char*& nextChar,ParseState& state)
{
	// Use David Gay's strtod to parse a floating point number.
	const char* firstChar = nextChar;
	F64 f64 = parseDecimalF64(nextChar,const_cast<char**>(&nextChar));
	if(nextChar == firstChar)
	{
		++nextChar;
		Errors::fatalf("strtod failed to parse number accepted by lexer");
	}
	if(f64 < std::numeric_limits<Float>::lowest() || f64 > std::numeric_limits<Float>::max())
	{
		parseErrorf(state,firstChar,"float literal is too large");
	}

	return (Float)f64;
}

// Parses a hexadecimal floating point literal, advancing nextChar past the parsed characters.
// Assumes it will only be called for input that's already been accepted by the lexer as a hexadecimal float literal.
template<typename Float>
Float parseHexFloat(const char*& nextChar,ParseState& state)
{
	typedef typename Floats::FloatComponents<Float> FloatComponents;
	typedef typename FloatComponents::Bits FloatBits;
	FloatComponents resultComponents;

	resultComponents.bits.sign = parseSign(nextChar) ? 1 : 0;

	assert(nextChar[0] == '0' && (nextChar[1] == 'x' || nextChar[1] == 'X'));
	nextChar += 2;

	// Parse hexits into a 64-bit fixed point number, keeping track of where the point is in exponent.
	U64 fixedPoI64 = 0;
	bool hasSeenPoint = false;
	I64 exponent = 0;
	while(true)
	{
		U8 hexit = 0;
		if(tryParseHexit(nextChar,hexit))
		{
			// Once there are too many hexits to accumulate in the 64-bit fixed point number, ignore
			// the hexits, but continue to update exponent so we get an accurate but imprecise number.
			if(fixedPoI64 <= (UINT64_MAX - 15) / 16)
			{
				assert(fixedPoI64 * 16 + hexit >= fixedPoI64);
				fixedPoI64 = fixedPoI64 * 16 + hexit;
				exponent -= hasSeenPoint ? 4 : 0;
			}
			else
			{
				exponent += hasSeenPoint ? 0 : 4;
			}
		}
		else if(*nextChar == '.')
		{
			assert(!hasSeenPoint);
			hasSeenPoint = true;
			++nextChar;
		}
		else { break; }
	}

	// Parse an optional exponent.
	if(*nextChar == 'p' || *nextChar == 'P')
	{
		++nextChar;
		const bool isExponentNegative = parseSign(nextChar);
		const U64 userExponent = parseDecimalUnsignedInt(nextChar,state,U64(-INT32_MIN),"float literal exponent");
		exponent = isExponentNegative ? exponent - userExponent : exponent + userExponent;
	}

	if(!fixedPoI64)
	{
		// If both the integer and fractional part are zero, just return zero.
		resultComponents.bits.exponent = 0;
		resultComponents.bits.significand = 0;
	}
	else
	{
		// Shift the fixed point number's most significant set bit into the MSB.
		const Uptr leadingZeroes = Platform::countLeadingZeroes(fixedPoI64);
		fixedPoI64 <<= leadingZeroes;
		exponent += 64;
		exponent -= leadingZeroes;

		const I64 exponentWithImplicitLeadingOne = exponent - 1;
		if(exponentWithImplicitLeadingOne > FloatComponents::maxNormalExponent)
		{
			// If the number is out of range, produce an error and return infinity.
			resultComponents.bits.exponent = FloatComponents::maxExponentBits;
			resultComponents.bits.significand = FloatComponents::maxSignificand;
			parseErrorf(state,state.nextToken,"hexadecimal float literal is out of range");
		}
		else if(exponentWithImplicitLeadingOne < FloatComponents::minNormalExponent)
		{
			// Denormals are encoded as if their exponent is minNormalExponent, but
			// with the significand shifted down to include the leading 1 that is implicit for
			// normal numbers, and with the encoded exponent = 0.
			const Uptr denormalShift = FloatComponents::minNormalExponent - exponent;
			fixedPoI64 = denormalShift >= 64 ? 0 : (fixedPoI64 >> denormalShift);
			resultComponents.bits.exponent = 0;
			resultComponents.bits.significand = FloatBits(fixedPoI64 >> (64 - FloatComponents::numSignificandBits));
		}
		else
		{
			// Encode a normal floating point value.
			assert(exponentWithImplicitLeadingOne >= FloatComponents::minNormalExponent);
			assert(exponentWithImplicitLeadingOne <= FloatComponents::maxNormalExponent);
			resultComponents.bits.exponent = FloatBits(exponentWithImplicitLeadingOne + FloatComponents::exponentBias);
			resultComponents.bits.significand = FloatBits(fixedPoI64 >> (63 - FloatComponents::numSignificandBits));
		}
	}

	return resultComponents.value;
}

// Tries to parse an numeric literal token as an integer, advancing state.nextToken.
// Returns true if it matched a token.
template<typename UnsignedInt>
bool tryParseInt(ParseState& state,UnsignedInt& outUnsignedInt,I64 minSignedValue,U64 maxUnsignedValue)
{
	bool isNegative = false;
	U64 u64 = 0;

	const char* nextChar = state.string + state.nextToken->begin;
	switch(state.nextToken->type)
	{
	case t_decimalInt:
		isNegative = parseSign(nextChar);
		u64 = parseDecimalUnsignedInt(nextChar,state,isNegative ? U64(-minSignedValue) : maxUnsignedValue,"int literal");
		break;
	case t_hexInt:
		isNegative = parseSign(nextChar);
		u64 = parseHexUnsignedInt(nextChar,state,isNegative ? U64(-minSignedValue) : maxUnsignedValue);
		break;
	default:
		return false;
	};

	outUnsignedInt = isNegative ? UnsignedInt(-I64(u64)) : UnsignedInt(u64);

	++state.nextToken;
	assert(nextChar <= state.string + state.nextToken->begin);

	return true;
}

// Tries to parse a numeric literal literal token as a float, advancing state.nextToken.
// Returns true if it matched a token.
template<typename Float>
bool tryParseFloat(ParseState& state,Float& outFloat)
{
	const char* nextChar = state.string + state.nextToken->begin;
	switch(state.nextToken->type)
	{
	case t_decimalInt:
	case t_decimalFloat: outFloat = parseDecimalFloat<Float>(nextChar,state); break;
	case t_hexInt:
	case t_hexFloat: outFloat = parseHexFloat<Float>(nextChar,state); break;
	case t_floatNaN: outFloat = parseNaN<Float>(nextChar,state); break;
	case t_floatInf: outFloat = parseInfinity<Float>(nextChar); break;
	default:
		parseErrorf(state,state.nextToken,"expected float literal");
		return false;
	};

	++state.nextToken;
	assert(nextChar <= state.string + state.nextToken->begin);

	return true;
}

namespace WAST
{
	bool tryParseI32(ParseState& state,U32& outI32)
	{
		return tryParseInt<U32>(state,outI32,INT32_MIN,UINT32_MAX);
	}

	bool tryParseI64(ParseState& state,U64& outI64)
	{
		return tryParseInt<U64>(state,outI64,INT64_MIN,UINT64_MAX);
	}

	U8 parseI8(ParseState& state)
	{
		U32 result;
		if(!tryParseInt<U32>(state,result,INT8_MIN,UINT8_MAX))
		{
			parseErrorf(state,state.nextToken,"expected i8 literal");
			throw RecoverParseException();
		}
		return U8(result);
	}

	U32 parseI32(ParseState& state)
	{
		U32 result;
		if(!tryParseI32(state,result))
		{
			parseErrorf(state,state.nextToken,"expected i32 literal");
			throw RecoverParseException();
		}
		return result;
	}

	U64 parseI64(ParseState& state)
	{
		U64 result;
		if(!tryParseI64(state,result))
		{
			parseErrorf(state,state.nextToken,"expected i64 literal");
			throw RecoverParseException();
		}
		return result;
	}

	F32 parseF32(ParseState& state)
	{
		F32 result;
		if(!tryParseFloat(state,result))
		{
			parseErrorf(state,state.nextToken,"expected f32 literal");
			throw RecoverParseException();
		}
		return result;
	}

	F64 parseF64(ParseState& state)
	{
		F64 result;
		if(!tryParseFloat(state,result))
		{
			parseErrorf(state,state.nextToken,"expected f64 literal");
			throw RecoverParseException();
		}
		return result;
	}
}<commit_msg>Try to fix non-MSVC compile error<commit_after>#include "Inline/BasicTypes.h"
#include "Inline/Floats.h"
#include "WAST.h"
#include "Lexer.h"
#include "Parse.h"

#include <climits>
#include <cerrno>

// Include the David Gay's dtoa code.
// #define strtod and dtoa to avoid conflicting with the C standard library versions
// This is complicated by dtoa.c including stdlib.h, so we need to also include stdlib.h
// here to ensure that it isn't included with the strtod and dtoa #define.
#include <stdlib.h>

#define IEEE_8087
#define NO_HEX_FP
#define NO_INFNAN_CHECK
#define strtod parseDecimalF64
#define dtoa printDecimalF64

#ifdef _MSC_VER
	#pragma warning(push)
	#pragma warning(disable : 4244 4083 4706 4701 4703)
#elif defined(__GNUC__) && !defined(__clang__)
	#pragma GCC diagnostic push
	#pragma GCC diagnostic ignored "-Wsign-compare"
	#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
	#define Long int
#else
	#pragma GCC diagnostic push
	#pragma GCC diagnostic ignored "-Wsign-compare"
	#define Long int
#endif

#include "../ThirdParty/dtoa.c"

#ifdef _MSC_VER
	#pragma warning(pop)
#else
	#pragma GCC diagnostic pop
	#undef Long
#endif

#undef IEEE_8087
#undef NO_HEX_FP
#undef NO_STRTOD_BIGCOMP
#undef NO_INFNAN_CHECK
#undef strtod
#undef dtoa

using namespace WAST;

// Parses an optional + or - sign and returns true if a - sign was parsed.
// If either a + or - sign is parsed, nextChar is advanced past it.
static bool parseSign(const char*& nextChar)
{
	if(*nextChar == '-') { ++nextChar; return true; }
	else if(*nextChar == '+') { ++nextChar; }
	return false;
}

// Parses an unsigned integer from hexits, starting with "0x", and advancing nextChar past the parsed hexits.
// be called for input that's already been accepted by the lexer as a hexadecimal integer.
static U64 parseHexUnsignedInt(const char*& nextChar,ParseState& state,U64 maxValue)
{
	const char* firstHexit = nextChar;
	assert(nextChar[0] == '0' && (nextChar[1] == 'x' || nextChar[1] == 'X'));
	nextChar += 2;

	U64 result = 0;
	U8 hexit = 0;
	while(tryParseHexit(nextChar,hexit))
	{
		if(result > (maxValue - hexit) / 16)
		{
			parseErrorf(state,firstHexit,"integer literal is too large");
			result = maxValue;
			while(tryParseHexit(nextChar,hexit)) {};
			break;
		}
		assert(result * 16 + hexit >= result);
		result = result * 16 + hexit;
	}
	return result;
}

// Parses an unsigned integer from digits, advancing nextChar past the parsed digits.
// Assumes it will only be called for input that's already been accepted by the lexer as a decimal integer.
static U64 parseDecimalUnsignedInt(const char*& nextChar,ParseState& state,U64 maxValue,const char* context)
{
	U64 result = 0;
	const char* firstDigit = nextChar;
	while(*nextChar >= '0' && *nextChar <= '9')
	{
		const U8 digit = *nextChar - '0';
		++nextChar;

		if(result > U64(maxValue - digit) / 10)
		{
			parseErrorf(state,firstDigit,"%s is too large",context);
			result = maxValue;
			while(*nextChar >= '0' && *nextChar <= '9') { ++nextChar; };
			break;
		}
		assert(result * 10 + digit >= result);
		result = result * 10 + digit;
	};
	return result;
}

// Parses a floating-point NaN, advancing nextChar past the parsed characters.
// Assumes it will only be called for input that's already been accepted by the lexer as a literal NaN.
template<typename Float>
Float parseNaN(const char*& nextChar,ParseState& state)
{
	typedef typename Floats::FloatComponents<Float> FloatComponents;
	FloatComponents resultComponents;
	resultComponents.bits.sign = parseSign(nextChar) ? 1 : 0;
	resultComponents.bits.exponent = FloatComponents::maxExponentBits;

	assert(nextChar[0] == 'n'
	&& nextChar[1] == 'a'
	&& nextChar[2] == 'n');
	nextChar += 3;

	if(*nextChar == ':')
	{
		++nextChar;

		const U64 significandBits = parseHexUnsignedInt(nextChar,state,FloatComponents::maxSignificand);
		resultComponents.bits.significand = typename FloatComponents::Bits(significandBits);
	}
	else
	{
		// If the NaN's significand isn't specified, just set the top bit.
		resultComponents.bits.significand = typename FloatComponents::Bits(1) << (FloatComponents::numSignificandBits-1);
	}

	return resultComponents.value;
}

// Parses a floating-point infinity. Does not advance nextChar.
// Assumes it will only be called for input that's already been accepted by the lexer as a literal infinity.
template<typename Float>
Float parseInfinity(const char* nextChar)
{
	// Floating point infinite is represented by max exponent with a zero significand.
	typedef typename Floats::FloatComponents<Float> FloatComponents;
	FloatComponents resultComponents;
	resultComponents.bits.sign = parseSign(nextChar) ? 1 : 0;
	resultComponents.bits.exponent = FloatComponents::maxExponentBits;
	resultComponents.bits.significand = 0;
	return resultComponents.value;
}

// Parses a decimal floating point literal, advancing nextChar past the parsed characters.
// Assumes it will only be called for input that's already been accepted by the lexer as a decimal float literal.
template<typename Float>
Float parseDecimalFloat(const char*& nextChar,ParseState& state)
{
	// Use David Gay's strtod to parse a floating point number.
	const char* firstChar = nextChar;
	F64 f64 = parseDecimalF64(nextChar,const_cast<char**>(&nextChar));
	if(nextChar == firstChar)
	{
		++nextChar;
		Errors::fatalf("strtod failed to parse number accepted by lexer");
	}
	if(f64 < std::numeric_limits<Float>::lowest() || f64 > std::numeric_limits<Float>::max())
	{
		parseErrorf(state,firstChar,"float literal is too large");
	}

	return (Float)f64;
}

// Parses a hexadecimal floating point literal, advancing nextChar past the parsed characters.
// Assumes it will only be called for input that's already been accepted by the lexer as a hexadecimal float literal.
template<typename Float>
Float parseHexFloat(const char*& nextChar,ParseState& state)
{
	typedef typename Floats::FloatComponents<Float> FloatComponents;
	typedef typename FloatComponents::Bits FloatBits;
	FloatComponents resultComponents;

	resultComponents.bits.sign = parseSign(nextChar) ? 1 : 0;

	assert(nextChar[0] == '0' && (nextChar[1] == 'x' || nextChar[1] == 'X'));
	nextChar += 2;

	// Parse hexits into a 64-bit fixed point number, keeping track of where the point is in exponent.
	U64 fixedPoI64 = 0;
	bool hasSeenPoint = false;
	I64 exponent = 0;
	while(true)
	{
		U8 hexit = 0;
		if(tryParseHexit(nextChar,hexit))
		{
			// Once there are too many hexits to accumulate in the 64-bit fixed point number, ignore
			// the hexits, but continue to update exponent so we get an accurate but imprecise number.
			if(fixedPoI64 <= (UINT64_MAX - 15) / 16)
			{
				assert(fixedPoI64 * 16 + hexit >= fixedPoI64);
				fixedPoI64 = fixedPoI64 * 16 + hexit;
				exponent -= hasSeenPoint ? 4 : 0;
			}
			else
			{
				exponent += hasSeenPoint ? 0 : 4;
			}
		}
		else if(*nextChar == '.')
		{
			assert(!hasSeenPoint);
			hasSeenPoint = true;
			++nextChar;
		}
		else { break; }
	}

	// Parse an optional exponent.
	if(*nextChar == 'p' || *nextChar == 'P')
	{
		++nextChar;
		const bool isExponentNegative = parseSign(nextChar);
		const U64 userExponent = parseDecimalUnsignedInt(nextChar,state,U64(-INT32_MIN),"float literal exponent");
		exponent = isExponentNegative ? exponent - userExponent : exponent + userExponent;
	}

	if(!fixedPoI64)
	{
		// If both the integer and fractional part are zero, just return zero.
		resultComponents.bits.exponent = 0;
		resultComponents.bits.significand = 0;
	}
	else
	{
		// Shift the fixed point number's most significant set bit into the MSB.
		const Uptr leadingZeroes = Platform::countLeadingZeroes(fixedPoI64);
		fixedPoI64 <<= leadingZeroes;
		exponent += 64;
		exponent -= leadingZeroes;

		const I64 exponentWithImplicitLeadingOne = exponent - 1;
		if(exponentWithImplicitLeadingOne > FloatComponents::maxNormalExponent)
		{
			// If the number is out of range, produce an error and return infinity.
			resultComponents.bits.exponent = FloatComponents::maxExponentBits;
			resultComponents.bits.significand = FloatComponents::maxSignificand;
			parseErrorf(state,state.nextToken,"hexadecimal float literal is out of range");
		}
		else if(exponentWithImplicitLeadingOne < FloatComponents::minNormalExponent)
		{
			// Denormals are encoded as if their exponent is minNormalExponent, but
			// with the significand shifted down to include the leading 1 that is implicit for
			// normal numbers, and with the encoded exponent = 0.
			const Uptr denormalShift = FloatComponents::minNormalExponent - exponent;
			fixedPoI64 = denormalShift >= 64 ? 0 : (fixedPoI64 >> denormalShift);
			resultComponents.bits.exponent = 0;
			resultComponents.bits.significand = FloatBits(fixedPoI64 >> (64 - FloatComponents::numSignificandBits));
		}
		else
		{
			// Encode a normal floating point value.
			assert(exponentWithImplicitLeadingOne >= FloatComponents::minNormalExponent);
			assert(exponentWithImplicitLeadingOne <= FloatComponents::maxNormalExponent);
			resultComponents.bits.exponent = FloatBits(exponentWithImplicitLeadingOne + FloatComponents::exponentBias);
			resultComponents.bits.significand = FloatBits(fixedPoI64 >> (63 - FloatComponents::numSignificandBits));
		}
	}

	return resultComponents.value;
}

// Tries to parse an numeric literal token as an integer, advancing state.nextToken.
// Returns true if it matched a token.
template<typename UnsignedInt>
bool tryParseInt(ParseState& state,UnsignedInt& outUnsignedInt,I64 minSignedValue,U64 maxUnsignedValue)
{
	bool isNegative = false;
	U64 u64 = 0;

	const char* nextChar = state.string + state.nextToken->begin;
	switch(state.nextToken->type)
	{
	case t_decimalInt:
		isNegative = parseSign(nextChar);
		u64 = parseDecimalUnsignedInt(nextChar,state,isNegative ? U64(-minSignedValue) : maxUnsignedValue,"int literal");
		break;
	case t_hexInt:
		isNegative = parseSign(nextChar);
		u64 = parseHexUnsignedInt(nextChar,state,isNegative ? U64(-minSignedValue) : maxUnsignedValue);
		break;
	default:
		return false;
	};

	outUnsignedInt = isNegative ? UnsignedInt(-I64(u64)) : UnsignedInt(u64);

	++state.nextToken;
	assert(nextChar <= state.string + state.nextToken->begin);

	return true;
}

// Tries to parse a numeric literal literal token as a float, advancing state.nextToken.
// Returns true if it matched a token.
template<typename Float>
bool tryParseFloat(ParseState& state,Float& outFloat)
{
	const char* nextChar = state.string + state.nextToken->begin;
	switch(state.nextToken->type)
	{
	case t_decimalInt:
	case t_decimalFloat: outFloat = parseDecimalFloat<Float>(nextChar,state); break;
	case t_hexInt:
	case t_hexFloat: outFloat = parseHexFloat<Float>(nextChar,state); break;
	case t_floatNaN: outFloat = parseNaN<Float>(nextChar,state); break;
	case t_floatInf: outFloat = parseInfinity<Float>(nextChar); break;
	default:
		parseErrorf(state,state.nextToken,"expected float literal");
		return false;
	};

	++state.nextToken;
	assert(nextChar <= state.string + state.nextToken->begin);

	return true;
}

namespace WAST
{
	bool tryParseI32(ParseState& state,U32& outI32)
	{
		return tryParseInt<U32>(state,outI32,INT32_MIN,UINT32_MAX);
	}

	bool tryParseI64(ParseState& state,U64& outI64)
	{
		return tryParseInt<U64>(state,outI64,INT64_MIN,UINT64_MAX);
	}

	U8 parseI8(ParseState& state)
	{
		U32 result;
		if(!tryParseInt<U32>(state,result,INT8_MIN,UINT8_MAX))
		{
			parseErrorf(state,state.nextToken,"expected i8 literal");
			throw RecoverParseException();
		}
		return U8(result);
	}

	U32 parseI32(ParseState& state)
	{
		U32 result;
		if(!tryParseI32(state,result))
		{
			parseErrorf(state,state.nextToken,"expected i32 literal");
			throw RecoverParseException();
		}
		return result;
	}

	U64 parseI64(ParseState& state)
	{
		U64 result;
		if(!tryParseI64(state,result))
		{
			parseErrorf(state,state.nextToken,"expected i64 literal");
			throw RecoverParseException();
		}
		return result;
	}

	F32 parseF32(ParseState& state)
	{
		F32 result;
		if(!tryParseFloat(state,result))
		{
			parseErrorf(state,state.nextToken,"expected f32 literal");
			throw RecoverParseException();
		}
		return result;
	}

	F64 parseF64(ParseState& state)
	{
		F64 result;
		if(!tryParseFloat(state,result))
		{
			parseErrorf(state,state.nextToken,"expected f64 literal");
			throw RecoverParseException();
		}
		return result;
	}
}<|endoftext|>


<commit_before>// @(#)root/foundation:
// Author: Axel Naumann, Enrico Guiraud, June 2017

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

#ifndef ROOT_TypeTraits
#define ROOT_TypeTraits

#include <memory> // shared_ptr, unique_ptr for IsSmartOrDumbPtr
#include <type_traits>
#include <vector> // for IsContainer
#include "ROOT/RSpan.hxx" // for IsContainer

namespace ROOT {

/// ROOT type_traits extensions
namespace TypeTraits {
/// Lightweight storage for a collection of types.
/// Differently from std::tuple, no instantiation of objects of stored types is performed
template <typename... Types>
struct TypeList {
   static constexpr std::size_t list_size = sizeof...(Types);
};
} // end ns TypeTraits

namespace Detail {
template <typename T> constexpr auto HasCallOp(int /*goodOverload*/) -> decltype(&T::operator(), true) { return true; }
template <typename T> constexpr bool HasCallOp(char /*badOverload*/) { return false; }

/// Extract types from the signature of a callable object. See CallableTraits.
template <typename T, bool HasCallOp = ROOT::Detail::HasCallOp<T>(0)>
struct CallableTraitsImpl {};

// Extract signature of operator() and delegate to the appropriate CallableTraitsImpl overloads
template <typename T>
struct CallableTraitsImpl<T, true> {
   using arg_types = typename CallableTraitsImpl<decltype(&T::operator())>::arg_types;
   using arg_types_nodecay = typename CallableTraitsImpl<decltype(&T::operator())>::arg_types_nodecay;
   using ret_type = typename CallableTraitsImpl<decltype(&T::operator())>::ret_type;
};

// lambdas, std::function, const member functions
template <typename R, typename T, typename... Args>
struct CallableTraitsImpl<R (T::*)(Args...) const, false> {
   using arg_types = ROOT::TypeTraits::TypeList<typename std::decay<Args>::type...>;
   using arg_types_nodecay = ROOT::TypeTraits::TypeList<Args...>;
   using ret_type = R;
};

// mutable lambdas and functor classes, non-const member functions
template <typename R, typename T, typename... Args>
struct CallableTraitsImpl<R (T::*)(Args...), false> {
   using arg_types = ROOT::TypeTraits::TypeList<typename std::decay<Args>::type...>;
   using arg_types_nodecay = ROOT::TypeTraits::TypeList<Args...>;
   using ret_type = R;
};

// function pointers
template <typename R, typename... Args>
struct CallableTraitsImpl<R (*)(Args...), false> {
   using arg_types = ROOT::TypeTraits::TypeList<typename std::decay<Args>::type...>;
   using arg_types_nodecay = ROOT::TypeTraits::TypeList<Args...>;
   using ret_type = R;
};

// free functions
template <typename R, typename... Args>
struct CallableTraitsImpl<R(Args...), false> {
   using arg_types = ROOT::TypeTraits::TypeList<typename std::decay<Args>::type...>;
   using arg_types_nodecay = ROOT::TypeTraits::TypeList<Args...>;
   using ret_type = R;
};
} // end ns Detail

namespace TypeTraits {

///\class ROOT::TypeTraits::
template <class T>
class IsSmartOrDumbPtr : public std::integral_constant<bool, std::is_pointer<T>::value> {
};

template <class P>
class IsSmartOrDumbPtr<std::shared_ptr<P>> : public std::true_type {
};

template <class P>
class IsSmartOrDumbPtr<std::unique_ptr<P>> : public std::true_type {
};

/// Check for container traits.
template <typename T>
struct IsContainer {
   using Test_t = typename std::decay<T>::type;

   template <typename A>
   static constexpr bool Test(A *pt, A const *cpt = nullptr, decltype(pt->begin()) * = nullptr,
                              decltype(pt->end()) * = nullptr, decltype(cpt->begin()) * = nullptr,
                              decltype(cpt->end()) * = nullptr, typename A::iterator *pi = nullptr,
                              typename A::const_iterator *pci = nullptr)
   {
      using It_t = typename A::iterator;
      using CIt_t = typename A::const_iterator;
      using V_t = typename A::value_type;
      return std::is_same<Test_t, std::vector<bool>>::value ||
             (std::is_same<decltype(pt->begin()), It_t>::value && std::is_same<decltype(pt->end()), It_t>::value &&
              std::is_same<decltype(cpt->begin()), CIt_t>::value && std::is_same<decltype(cpt->end()), CIt_t>::value &&
              std::is_same<decltype(**pi), V_t &>::value && std::is_same<decltype(**pci), V_t const &>::value);
   }

   template <typename A>
   static constexpr bool Test(...)
   {
      return false;
   }

   static constexpr bool value = Test<Test_t>(nullptr);
};

template<typename T>
struct IsContainer<std::span<T>> {
   static constexpr bool value = true;
};

/// Checks for signed integers types that are not characters
template<class T>
struct IsSignedNumeral : std::integral_constant<bool,
   std::is_integral<T>::value &&
   std::is_signed<T>::value &&
   !std::is_same<T, char>::value
> {};

/// Checks for unsigned integer types that are not characters
template<class T>
struct IsUnsignedNumeral : std::integral_constant<bool,
   std::is_integral<T>::value &&
   !std::is_signed<T>::value &&
   !std::is_same<T, char>::value
> {};

/// Checks for floating point types (that are not characters)
template<class T>
using IsFloatNumeral = std::is_floating_point<T>;

/// Extract types from the signature of a callable object.
/// The `CallableTraits` struct contains three type aliases:
///   - arg_types: a `TypeList` of all types in the signature, decayed through std::decay
///   - arg_types_nodecay: a `TypeList` of all types in the signature, including cv-qualifiers
template<typename F>
using CallableTraits = ROOT::Detail::CallableTraitsImpl<F>;

// Return first of a variadic list of types.
template <typename T, typename... Rest>
struct TakeFirstType {
   using type = T;
};

template <typename... Types>
using TakeFirstType_t = typename TakeFirstType<Types...>::type;

// Remove first type from a variadic list of types, return a TypeList containing the rest.
// e.g. RemoveFirst_t<A,B,C> is TypeList<B,C>
template <typename T, typename... Rest>
struct RemoveFirst {
   using type = TypeList<Rest...>;
};

template <typename... Args>
using RemoveFirst_t = typename RemoveFirst<Args...>::type;

/// Return first of possibly many template parameters.
/// For non-template types, the result is void
/// e.g. TakeFirstParameter<U<A,B>> is A
///      TakeFirstParameter<T> is void
template <typename T>
struct TakeFirstParameter {
   using type = void;
};

template <template <typename...> class Template, typename T, typename... Rest>
struct TakeFirstParameter<Template<T, Rest...>> {
   using type = T;
};

template <typename T>
using TakeFirstParameter_t = typename TakeFirstParameter<T>::type;

/// Remove first of possibly many template parameters.
/// e.g. RemoveFirstParameter_t<U<A,B>> is U<B>
template <typename>
struct RemoveFirstParameter {
};

template <typename T, template <typename...> class U, typename... Rest>
struct RemoveFirstParameter<U<T, Rest...>> {
   using type = U<Rest...>;
};

template <typename T>
using RemoveFirstParameter_t = typename RemoveFirstParameter<T>::type;

template <typename T>
struct HasBeginAndEnd {
   template <typename V>
   static char (&b(
      typename std::enable_if<std::is_same<decltype(static_cast<typename V::const_iterator (V::*)() const>(&V::begin)),
                                           typename V::const_iterator (V::*)() const>::value,
                              void>::type *))[1];

   template <typename V>
   static char (&b(...))[2];

   template <typename V>
   static char (
      &e(typename std::enable_if<std::is_same<decltype(static_cast<typename V::const_iterator (V::*)() const>(&V::end)),
                                              typename V::const_iterator (V::*)() const>::value,
                                 void>::type *))[1];

   template <typename V>
   static char (&e(...))[2];

   static constexpr bool const begin_value = sizeof(b<T>(0)) == 1;
   static constexpr bool const end_value = sizeof(e<T>(0)) == 1;
   static constexpr bool const value = begin_value && end_value;
};

} // ns TypeTraits
} // ns ROOT
#endif // ROOT_TTypeTraits
<commit_msg>[Core] Simplify the implementation of the HasBeginAndEnd utility.<commit_after>// @(#)root/foundation:
// Author: Axel Naumann, Enrico Guiraud, June 2017

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

#ifndef ROOT_TypeTraits
#define ROOT_TypeTraits

#include <memory> // shared_ptr, unique_ptr for IsSmartOrDumbPtr
#include <type_traits>
#include <vector> // for IsContainer
#include "ROOT/RSpan.hxx" // for IsContainer

namespace ROOT {

/// ROOT type_traits extensions
namespace TypeTraits {
/// Lightweight storage for a collection of types.
/// Differently from std::tuple, no instantiation of objects of stored types is performed
template <typename... Types>
struct TypeList {
   static constexpr std::size_t list_size = sizeof...(Types);
};
} // end ns TypeTraits

namespace Detail {
template <typename T> constexpr auto HasCallOp(int /*goodOverload*/) -> decltype(&T::operator(), true) { return true; }
template <typename T> constexpr bool HasCallOp(char /*badOverload*/) { return false; }

/// Extract types from the signature of a callable object. See CallableTraits.
template <typename T, bool HasCallOp = ROOT::Detail::HasCallOp<T>(0)>
struct CallableTraitsImpl {};

// Extract signature of operator() and delegate to the appropriate CallableTraitsImpl overloads
template <typename T>
struct CallableTraitsImpl<T, true> {
   using arg_types = typename CallableTraitsImpl<decltype(&T::operator())>::arg_types;
   using arg_types_nodecay = typename CallableTraitsImpl<decltype(&T::operator())>::arg_types_nodecay;
   using ret_type = typename CallableTraitsImpl<decltype(&T::operator())>::ret_type;
};

// lambdas, std::function, const member functions
template <typename R, typename T, typename... Args>
struct CallableTraitsImpl<R (T::*)(Args...) const, false> {
   using arg_types = ROOT::TypeTraits::TypeList<typename std::decay<Args>::type...>;
   using arg_types_nodecay = ROOT::TypeTraits::TypeList<Args...>;
   using ret_type = R;
};

// mutable lambdas and functor classes, non-const member functions
template <typename R, typename T, typename... Args>
struct CallableTraitsImpl<R (T::*)(Args...), false> {
   using arg_types = ROOT::TypeTraits::TypeList<typename std::decay<Args>::type...>;
   using arg_types_nodecay = ROOT::TypeTraits::TypeList<Args...>;
   using ret_type = R;
};

// function pointers
template <typename R, typename... Args>
struct CallableTraitsImpl<R (*)(Args...), false> {
   using arg_types = ROOT::TypeTraits::TypeList<typename std::decay<Args>::type...>;
   using arg_types_nodecay = ROOT::TypeTraits::TypeList<Args...>;
   using ret_type = R;
};

// free functions
template <typename R, typename... Args>
struct CallableTraitsImpl<R(Args...), false> {
   using arg_types = ROOT::TypeTraits::TypeList<typename std::decay<Args>::type...>;
   using arg_types_nodecay = ROOT::TypeTraits::TypeList<Args...>;
   using ret_type = R;
};
} // end ns Detail

namespace TypeTraits {

///\class ROOT::TypeTraits::
template <class T>
class IsSmartOrDumbPtr : public std::integral_constant<bool, std::is_pointer<T>::value> {
};

template <class P>
class IsSmartOrDumbPtr<std::shared_ptr<P>> : public std::true_type {
};

template <class P>
class IsSmartOrDumbPtr<std::unique_ptr<P>> : public std::true_type {
};

/// Check for container traits.
template <typename T>
struct IsContainer {
   using Test_t = typename std::decay<T>::type;

   template <typename A>
   static constexpr bool Test(A *pt, A const *cpt = nullptr, decltype(pt->begin()) * = nullptr,
                              decltype(pt->end()) * = nullptr, decltype(cpt->begin()) * = nullptr,
                              decltype(cpt->end()) * = nullptr, typename A::iterator *pi = nullptr,
                              typename A::const_iterator *pci = nullptr)
   {
      using It_t = typename A::iterator;
      using CIt_t = typename A::const_iterator;
      using V_t = typename A::value_type;
      return std::is_same<Test_t, std::vector<bool>>::value ||
             (std::is_same<decltype(pt->begin()), It_t>::value && std::is_same<decltype(pt->end()), It_t>::value &&
              std::is_same<decltype(cpt->begin()), CIt_t>::value && std::is_same<decltype(cpt->end()), CIt_t>::value &&
              std::is_same<decltype(**pi), V_t &>::value && std::is_same<decltype(**pci), V_t const &>::value);
   }

   template <typename A>
   static constexpr bool Test(...)
   {
      return false;
   }

   static constexpr bool value = Test<Test_t>(nullptr);
};

template<typename T>
struct IsContainer<std::span<T>> {
   static constexpr bool value = true;
};

/// Checks for signed integers types that are not characters
template<class T>
struct IsSignedNumeral : std::integral_constant<bool,
   std::is_integral<T>::value &&
   std::is_signed<T>::value &&
   !std::is_same<T, char>::value
> {};

/// Checks for unsigned integer types that are not characters
template<class T>
struct IsUnsignedNumeral : std::integral_constant<bool,
   std::is_integral<T>::value &&
   !std::is_signed<T>::value &&
   !std::is_same<T, char>::value
> {};

/// Checks for floating point types (that are not characters)
template<class T>
using IsFloatNumeral = std::is_floating_point<T>;

/// Extract types from the signature of a callable object.
/// The `CallableTraits` struct contains three type aliases:
///   - arg_types: a `TypeList` of all types in the signature, decayed through std::decay
///   - arg_types_nodecay: a `TypeList` of all types in the signature, including cv-qualifiers
template<typename F>
using CallableTraits = ROOT::Detail::CallableTraitsImpl<F>;

// Return first of a variadic list of types.
template <typename T, typename... Rest>
struct TakeFirstType {
   using type = T;
};

template <typename... Types>
using TakeFirstType_t = typename TakeFirstType<Types...>::type;

// Remove first type from a variadic list of types, return a TypeList containing the rest.
// e.g. RemoveFirst_t<A,B,C> is TypeList<B,C>
template <typename T, typename... Rest>
struct RemoveFirst {
   using type = TypeList<Rest...>;
};

template <typename... Args>
using RemoveFirst_t = typename RemoveFirst<Args...>::type;

/// Return first of possibly many template parameters.
/// For non-template types, the result is void
/// e.g. TakeFirstParameter<U<A,B>> is A
///      TakeFirstParameter<T> is void
template <typename T>
struct TakeFirstParameter {
   using type = void;
};

template <template <typename...> class Template, typename T, typename... Rest>
struct TakeFirstParameter<Template<T, Rest...>> {
   using type = T;
};

template <typename T>
using TakeFirstParameter_t = typename TakeFirstParameter<T>::type;

/// Remove first of possibly many template parameters.
/// e.g. RemoveFirstParameter_t<U<A,B>> is U<B>
template <typename>
struct RemoveFirstParameter {
};

template <typename T, template <typename...> class U, typename... Rest>
struct RemoveFirstParameter<U<T, Rest...>> {
   using type = U<Rest...>;
};

template <typename T>
using RemoveFirstParameter_t = typename RemoveFirstParameter<T>::type;

template <typename T>
struct HasBeginAndEnd {

   template <typename V>
   using Begin_t = typename V::const_iterator (V::*)() const;

   template <typename V>
   using End_t = typename V::const_iterator (V::*)() const;

   template <typename V>
   static constexpr auto Check(int)
      -> decltype(static_cast<Begin_t<V>>(&V::begin), static_cast<End_t<V>>(&V::end), true)
   {
      return true;
   }

   template <typename V>
   static constexpr bool Check(...)
   {
      return false;
   }

   static constexpr bool const value = Check<T>(0);
};

} // ns TypeTraits
} // ns ROOT
#endif // ROOT_TTypeTraits
<|endoftext|>


<commit_before>// Copyright (c) 2010-2020, Lawrence Livermore National Security, LLC. Produced
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
// LICENSE and NOTICE for details. LLNL-CODE-806117.
//
// This file is part of the MFEM library. For more information and source code
// availability visit https://mfem.org.
//
// MFEM is free software; you can redistribute it and/or modify it under the
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.

#include "mfem.hpp"
#include "catch.hpp"

#ifdef MFEM_USE_EXCEPTIONS

using namespace mfem;

namespace qf_coeff
{

TEST_CASE("Quadrature Function Coefficients",
          "[Quadrature Function Coefficients]")
{
   int order_h1 = 1, n = 3, dim = 3;
   double tol = 1e-9;

   Mesh mesh(n, n, n, Element::HEXAHEDRON, false, 1.0, 1.0, 1.0);

   int intOrder = 2 * order_h1 + 1;

   QuadratureSpace qspace(&mesh, intOrder);
   QuadratureFunction quadf_coeff(&qspace, 1);
   QuadratureFunction quadf_vcoeff(&qspace, dim);

   {
      int nelems = quadf_coeff.Size() / quadf_coeff.GetVDim();
      int vdim = quadf_coeff.GetVDim();

      for (int i = 0; i < nelems; i++)
      {
         for (int j = 0; j < vdim; j++)
         {
            quadf_coeff((i * vdim) + j) = 1.0;
         }
      }
   }

   {
      int nelems = quadf_vcoeff.Size() / quadf_vcoeff.GetVDim();
      int vdim = quadf_vcoeff.GetVDim();

      for (int i = 0; i < nelems; i++)
      {
         for (int j = 0; j < vdim; j++)
         {
            quadf_vcoeff((i * vdim) + j) = j;
         }
      }
   }

   QuadratureFunctionCoefficient qfc(&quadf_coeff);
   VectorQuadratureFunctionCoefficient qfvc(&quadf_vcoeff);

   SECTION("Operators on VecQuadFuncCoeff")
   {
      std::cout << "Testing VecQuadFuncCoeff: " << std::endl;
      std::cout << " Setting Index" << std::endl;
      REQUIRE_THROWS(qfvc.SetIndex(3));
      REQUIRE_THROWS(qfvc.SetIndex(-1));
      REQUIRE_NOTHROW(qfvc.SetIndex(1));
      qfvc.SetIndex(0);
      std::cout << " Setting Length" << std::endl;
      REQUIRE_THROWS(qfvc.SetLength(4));
      qfvc.SetIndex(1);
      REQUIRE_THROWS(qfvc.SetLength(3));
      REQUIRE_NOTHROW(qfvc.SetLength(2));
      REQUIRE_THROWS(qfvc.SetLength(0));
      qfvc.SetIndex(0);
      qfvc.SetLength(3);

      SECTION("Gridfunction L2 tests")
      {
         L2_FECollection    fec_l2(order_h1, dim);
         FiniteElementSpace fespace_l2(&mesh, &fec_l2, dim);
         GridFunction g0(&fespace_l2);
         GridFunction gtrue(&fespace_l2);

         {
            int nnodes = gtrue.Size() / dim;
            int vdim = dim;

            for (int i = 0; i < vdim; i++)
            {
               for (int j = 0; j < nnodes; j++)
               {
                  gtrue((i * nnodes) + j) = i;
               }
            }
         }

         g0 = 0.0;
         g0.ProjectDiscCoefficient(qfvc, GridFunction::ARITHMETIC);
         gtrue -= g0;
         REQUIRE(gtrue.Norml2() < tol);
      }

      SECTION("Gridfunction H1 tests")
      {
         L2_FECollection    fec_h1(order_h1, dim);
         FiniteElementSpace fespace_h1(&mesh, &fec_h1, dim);
         GridFunction g0(&fespace_h1);
         GridFunction gtrue(&fespace_h1);

         {
            int nnodes = gtrue.Size() / dim;
            int vdim = dim;

            for (int i = 0; i < vdim; i++)
            {
               for (int j = 0; j < nnodes; j++)
               {
                  gtrue((i * nnodes) + j) = i;
               }
            }
         }

         g0 = 0.0;
         g0.ProjectCoefficient(qfvc);
         gtrue -= g0;
         REQUIRE(gtrue.Norml2() < tol);
      }
   }

   SECTION("Operators on QuadFuncCoeff")
   {
      SECTION("Gridfunction L2 tests")
      {
         L2_FECollection    fec_l2(order_h1, dim);
         FiniteElementSpace fespace_l2(&mesh, &fec_l2, 1);
         GridFunction g0(&fespace_l2);
         GridFunction gtrue(&fespace_l2);

         {
            int nnodes = gtrue.Size();
            int vdim = 1;

            for (int i = 0; i < vdim; i++)
            {
               for (int j = 0; j < nnodes; j++)
               {
                  gtrue((i * nnodes) + j) = 1.0;
               }
            }
         }

         g0 = 0.0;
         g0.ProjectDiscCoefficient(qfc, GridFunction::ARITHMETIC);
         gtrue -= g0;
         REQUIRE(gtrue.Norml2() < tol);
      }

      SECTION("Gridfunction H1 tests")
      {
         L2_FECollection    fec_h1(order_h1, dim);
         FiniteElementSpace fespace_h1(&mesh, &fec_h1, 1);
         GridFunction g0(&fespace_h1);
         GridFunction gtrue(&fespace_h1);

         {
            int nnodes = gtrue.Size();
            int vdim = 1;

            for (int i = 0; i < vdim; i++)
            {
               for (int j = 0; j < nnodes; j++)
               {
                  gtrue((i * nnodes) + j) = 1.0;
               }
            }
         }

         g0 = 0.0;
         g0.ProjectCoefficient(qfc);
         gtrue -= g0;
         REQUIRE(gtrue.Norml2() < tol);
      }
   }
}

} // namespace qf_coeff

#endif  // MFEM_USE_EXCEPTIONS
<commit_msg>unit test fixes<commit_after>// Copyright (c) 2010-2020, Lawrence Livermore National Security, LLC. Produced
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
// LICENSE and NOTICE for details. LLNL-CODE-806117.
//
// This file is part of the MFEM library. For more information and source code
// availability visit https://mfem.org.
//
// MFEM is free software; you can redistribute it and/or modify it under the
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.

#include "mfem.hpp"
#include "catch.hpp"

using namespace mfem;

namespace qf_coeff
{

TEST_CASE("Quadrature Function Coefficients",
          "[Quadrature Function Coefficients]")
{
   int order_h1 = 1, n = 3, dim = 3;
   double tol = 1e-9;

   Mesh mesh(n, n, n, Element::HEXAHEDRON, false, 1.0, 1.0, 1.0);

   int intOrder = 2 * order_h1 + 1;

   QuadratureSpace qspace(&mesh, intOrder);
   QuadratureFunction quadf_coeff(&qspace, 1);
   QuadratureFunction quadf_vcoeff(&qspace, dim);

   {
      int nelems = quadf_coeff.Size() / quadf_coeff.GetVDim();
      int vdim = quadf_coeff.GetVDim();

      for (int i = 0; i < nelems; i++)
      {
         for (int j = 0; j < vdim; j++)
         {
            quadf_coeff((i * vdim) + j) = 1.0;
         }
      }
   }

   {
      int nelems = quadf_vcoeff.Size() / quadf_vcoeff.GetVDim();
      int vdim = quadf_vcoeff.GetVDim();

      for (int i = 0; i < nelems; i++)
      {
         for (int j = 0; j < vdim; j++)
         {
            quadf_vcoeff((i * vdim) + j) = j;
         }
      }
   }

   QuadratureFunctionCoefficient qfc(&quadf_coeff);
   VectorQuadratureFunctionCoefficient qfvc(&quadf_vcoeff);

   SECTION("Operators on VecQuadFuncCoeff")
   {
      std::cout << "Testing VecQuadFuncCoeff: " << std::endl;
#ifdef MFEM_USE_EXCEPTIONS
      std::cout << " Setting Index" << std::endl;
      REQUIRE_THROWS(qfvc.SetIndex(3));
      REQUIRE_THROWS(qfvc.SetIndex(-1));
      REQUIRE_NOTHROW(qfvc.SetIndex(1));
      qfvc.SetIndex(0);
      std::cout << " Setting Length" << std::endl;
      REQUIRE_THROWS(qfvc.SetLength(4));
      qfvc.SetIndex(1);
      REQUIRE_THROWS(qfvc.SetLength(3));
      REQUIRE_NOTHROW(qfvc.SetLength(2));
      REQUIRE_THROWS(qfvc.SetLength(0));
#endif
      qfvc.SetIndex(0);
      qfvc.SetLength(3);

      SECTION("Gridfunction L2 tests")
      {
         std::cout << "  Testing GridFunc L2 projection" << std::endl;
         L2_FECollection    fec_l2(order_h1, dim);
         FiniteElementSpace fespace_l2(&mesh, &fec_l2, dim);
         GridFunction g0(&fespace_l2);
         GridFunction gtrue(&fespace_l2);

         {
            int nnodes = gtrue.Size() / dim;
            int vdim = dim;

            for (int i = 0; i < vdim; i++)
            {
               for (int j = 0; j < nnodes; j++)
               {
                  gtrue((i * nnodes) + j) = i;
               }
            }
         }

         g0 = 0.0;
         g0.ProjectDiscCoefficient(qfvc, GridFunction::ARITHMETIC);
         gtrue -= g0;
         REQUIRE(gtrue.Norml2() < tol);
      }

      SECTION("Gridfunction H1 tests")
      {
         std::cout << "  Testing GridFunc H1 projection" << std::endl;
         H1_FECollection    fec_h1(order_h1, dim);
         FiniteElementSpace fespace_h1(&mesh, &fec_h1, dim);
         GridFunction g0(&fespace_h1);
         GridFunction gtrue(&fespace_h1);

         {
            int nnodes = gtrue.Size() / dim;
            int vdim = dim;

            for (int i = 0; i < vdim; i++)
            {
               for (int j = 0; j < nnodes; j++)
               {
                  gtrue((i * nnodes) + j) = i;
               }
            }
         }

         g0 = 0.0;
         g0.ProjectCoefficient(qfvc);
         gtrue -= g0;
         REQUIRE(gtrue.Norml2() < tol);
      }
   }

   SECTION("Operators on QuadFuncCoeff")
   {
      SECTION("Gridfunction L2 tests")
      {
         std::cout << "Testing QuadFuncCoeff:";
         std::cout << "  Testing GridFunc L2 projection" << std::endl;
         L2_FECollection    fec_l2(order_h1, dim);
         FiniteElementSpace fespace_l2(&mesh, &fec_l2, 1);
         GridFunction g0(&fespace_l2);
         GridFunction gtrue(&fespace_l2);

         {
            int nnodes = gtrue.Size();
            int vdim = 1;

            for (int i = 0; i < vdim; i++)
            {
               for (int j = 0; j < nnodes; j++)
               {
                  gtrue((i * nnodes) + j) = 1.0;
               }
            }
         }

         g0 = 0.0;
         g0.ProjectDiscCoefficient(qfc, GridFunction::ARITHMETIC);
         gtrue -= g0;
         REQUIRE(gtrue.Norml2() < tol);
      }

      SECTION("Gridfunction H1 tests")
      {
         std::cout << "  Testing GridFunc H1 projection" << std::endl;
         H1_FECollection    fec_h1(order_h1, dim);
         FiniteElementSpace fespace_h1(&mesh, &fec_h1, 1);
         GridFunction g0(&fespace_h1);
         GridFunction gtrue(&fespace_h1);

         {
            int nnodes = gtrue.Size();
            int vdim = 1;

            for (int i = 0; i < vdim; i++)
            {
               for (int j = 0; j < nnodes; j++)
               {
                  gtrue((i * nnodes) + j) = 1.0;
               }
            }
         }

         g0 = 0.0;
         g0.ProjectCoefficient(qfc);
         gtrue -= g0;
         REQUIRE(gtrue.Norml2() < tol);
      }
   }
}

} // namespace qf_coeff

<|endoftext|>


<commit_before>// @(#)root/foundation:
// Author: Axel Naumann, 2017-06-02

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

#ifndef ROOT_TypeTraits
#define ROOT_TypeTraits

#include <type_traits>

namespace ROOT {

/// ROOT type_traits extensions
namespace TypeTraits {

///\class ROOT::TypeTraits::
template <class T>
class IsSmartOrDumbPtr: public std::integral_constant<bool, std::is_pointer<T>::value> {};

template <class P>
class IsSmartOrDumbPtr<std::shared_ptr<P>>: public std::true_type {};

template <class P>
class IsSmartOrDumbPtr<std::unique_ptr<P>>: public std::true_type {};

/// Check for container traits.
template <typename T>
struct IsContainer {
   using Test_t = typename std::decay<T>::type;

   template <typename A>
   static constexpr bool Test(A *pt, A const *cpt = nullptr, decltype(pt->begin()) * = nullptr,
                              decltype(pt->end()) * = nullptr, decltype(cpt->begin()) * = nullptr,
                              decltype(cpt->end()) * = nullptr, typename A::iterator *pi = nullptr,
                              typename A::const_iterator *pci = nullptr)
   {
      using It_t = typename A::iterator;
      using CIt_t = typename A::const_iterator;
      using V_t = typename A::value_type;
      return std::is_same<Test_t, std::vector<bool>>::value ||
             (std::is_same<decltype(pt->begin()), It_t>::value && std::is_same<decltype(pt->end()), It_t>::value &&
              std::is_same<decltype(cpt->begin()), CIt_t>::value && std::is_same<decltype(cpt->end()), CIt_t>::value &&
              std::is_same<decltype(**pi), V_t &>::value && std::is_same<decltype(**pci), V_t const &>::value);
   }

   template <typename A>
   static constexpr bool Test(...)
   {
      return false;
   }

   static constexpr bool value = Test<Test_t>(nullptr);
};

/// Lightweight storage for a collection of types.
/// Differently from std::tuple, no instantiation of objects of stored types is performed
template <typename... Types>
struct TypeList {
   static constexpr std::size_t list_size = sizeof...(Types);
};

/// Extract types from the signature of a callable object.
template <typename T>
struct CallableTraits {
   using arg_types = typename CallableTraits<decltype(&T::operator())>::arg_types;
   using arg_types_nodecay = typename CallableTraits<decltype(&T::operator())>::arg_types_nodecay;
   using ret_type = typename CallableTraits<decltype(&T::operator())>::ret_type;
};

// lambdas and std::function
template <typename R, typename T, typename... Args>
struct CallableTraits<R (T::*)(Args...) const> {
   using arg_types = TypeList<typename std::decay<Args>::type...>;
   using arg_types_nodecay = TypeList<Args...>;
   using ret_type = R;
};

// mutable lambdas and functor classes
template <typename R, typename T, typename... Args>
struct CallableTraits<R (T::*)(Args...)> {
   using arg_types = TypeList<typename std::decay<Args>::type...>;
   using arg_types_nodecay = TypeList<Args...>;
   using ret_type = R;
};

// function pointers
template <typename R, typename... Args>
struct CallableTraits<R (*)(Args...)> {
   using arg_types = TypeList<typename std::decay<Args>::type...>;
   using arg_types_nodecay = TypeList<Args...>;
   using ret_type = R;
};

// free functions
template <typename R, typename... Args>
struct CallableTraits<R(Args...)> {
   using arg_types = TypeList<typename std::decay<Args>::type...>;
   using arg_types_nodecay = TypeList<Args...>;
   using ret_type = R;
};

// Return first of a variadic list of types.
template <typename T, typename...Rest>
struct TakeFirst {
   using type = T;
};

template <typename...Types>
using TakeFirst_t = typename TakeFirst<Types...>::type;

// Remove first type from a variadic list of types, return a TypeList containing the rest.
// e.g. RemoveFirst_t<A,B,C> is TypeList<B,C>
template<typename T, typename...Rest>
struct RemoveFirst {
   using type = TypeList<Rest...>;
};

template<typename...Args>
using RemoveFirst_t = typename RemoveFirst<Args...>::type;

/// Return first of possibly many template parameters.
/// For non-template types, the result is the type itself.
/// e.g. TakeFirstParameter<U<A,B>> is A
///      TakeFirstParameter<T> is T
template <typename T>
struct TakeFirstParameter {
   using type = void;
};

template <template <typename...> class Template, typename T, typename... Rest>
struct TakeFirstParameter<Template<T, Rest...>> {
   using type = T;
};

template <typename T>
using TakeFirstParameter_t = typename TakeFirstParameter<T>::type;

/// Remove first of possibly many template parameters.
/// e.g. RemoveFirstParameter_t<U<A,B>> is U<B>
template <typename>
struct RemoveFirstParameter {
};

template <typename T, template <typename...> class U, typename...Rest>
struct RemoveFirstParameter<U<T, Rest...>> {
   using type = U<Rest...>;
};

template <typename T>
using RemoveFirstParameter_t = typename RemoveFirstParameter<T>::type;

} // ns ROOT
} // ns TypeTraits
#endif //ROOT_TTypeTraits
<commit_msg>[TypeTraits] Add missing includes to TypeTraits.hxx<commit_after>// @(#)root/foundation:
// Author: Axel Naumann, 2017-06-02

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

#ifndef ROOT_TypeTraits
#define ROOT_TypeTraits

#include <memory> // shared_ptr, unique_ptr for IsSmartOrDumbPtr
#include <type_traits>
#include <vector> // for IsContainer

namespace ROOT {

/// ROOT type_traits extensions
namespace TypeTraits {

///\class ROOT::TypeTraits::
template <class T>
class IsSmartOrDumbPtr: public std::integral_constant<bool, std::is_pointer<T>::value> {};

template <class P>
class IsSmartOrDumbPtr<std::shared_ptr<P>>: public std::true_type {};

template <class P>
class IsSmartOrDumbPtr<std::unique_ptr<P>>: public std::true_type {};

/// Check for container traits.
template <typename T>
struct IsContainer {
   using Test_t = typename std::decay<T>::type;

   template <typename A>
   static constexpr bool Test(A *pt, A const *cpt = nullptr, decltype(pt->begin()) * = nullptr,
                              decltype(pt->end()) * = nullptr, decltype(cpt->begin()) * = nullptr,
                              decltype(cpt->end()) * = nullptr, typename A::iterator *pi = nullptr,
                              typename A::const_iterator *pci = nullptr)
   {
      using It_t = typename A::iterator;
      using CIt_t = typename A::const_iterator;
      using V_t = typename A::value_type;
      return std::is_same<Test_t, std::vector<bool>>::value ||
             (std::is_same<decltype(pt->begin()), It_t>::value && std::is_same<decltype(pt->end()), It_t>::value &&
              std::is_same<decltype(cpt->begin()), CIt_t>::value && std::is_same<decltype(cpt->end()), CIt_t>::value &&
              std::is_same<decltype(**pi), V_t &>::value && std::is_same<decltype(**pci), V_t const &>::value);
   }

   template <typename A>
   static constexpr bool Test(...)
   {
      return false;
   }

   static constexpr bool value = Test<Test_t>(nullptr);
};

/// Lightweight storage for a collection of types.
/// Differently from std::tuple, no instantiation of objects of stored types is performed
template <typename... Types>
struct TypeList {
   static constexpr std::size_t list_size = sizeof...(Types);
};

/// Extract types from the signature of a callable object.
template <typename T>
struct CallableTraits {
   using arg_types = typename CallableTraits<decltype(&T::operator())>::arg_types;
   using arg_types_nodecay = typename CallableTraits<decltype(&T::operator())>::arg_types_nodecay;
   using ret_type = typename CallableTraits<decltype(&T::operator())>::ret_type;
};

// lambdas and std::function
template <typename R, typename T, typename... Args>
struct CallableTraits<R (T::*)(Args...) const> {
   using arg_types = TypeList<typename std::decay<Args>::type...>;
   using arg_types_nodecay = TypeList<Args...>;
   using ret_type = R;
};

// mutable lambdas and functor classes
template <typename R, typename T, typename... Args>
struct CallableTraits<R (T::*)(Args...)> {
   using arg_types = TypeList<typename std::decay<Args>::type...>;
   using arg_types_nodecay = TypeList<Args...>;
   using ret_type = R;
};

// function pointers
template <typename R, typename... Args>
struct CallableTraits<R (*)(Args...)> {
   using arg_types = TypeList<typename std::decay<Args>::type...>;
   using arg_types_nodecay = TypeList<Args...>;
   using ret_type = R;
};

// free functions
template <typename R, typename... Args>
struct CallableTraits<R(Args...)> {
   using arg_types = TypeList<typename std::decay<Args>::type...>;
   using arg_types_nodecay = TypeList<Args...>;
   using ret_type = R;
};

// Return first of a variadic list of types.
template <typename T, typename...Rest>
struct TakeFirst {
   using type = T;
};

template <typename...Types>
using TakeFirst_t = typename TakeFirst<Types...>::type;

// Remove first type from a variadic list of types, return a TypeList containing the rest.
// e.g. RemoveFirst_t<A,B,C> is TypeList<B,C>
template<typename T, typename...Rest>
struct RemoveFirst {
   using type = TypeList<Rest...>;
};

template<typename...Args>
using RemoveFirst_t = typename RemoveFirst<Args...>::type;

/// Return first of possibly many template parameters.
/// For non-template types, the result is the type itself.
/// e.g. TakeFirstParameter<U<A,B>> is A
///      TakeFirstParameter<T> is T
template <typename T>
struct TakeFirstParameter {
   using type = void;
};

template <template <typename...> class Template, typename T, typename... Rest>
struct TakeFirstParameter<Template<T, Rest...>> {
   using type = T;
};

template <typename T>
using TakeFirstParameter_t = typename TakeFirstParameter<T>::type;

/// Remove first of possibly many template parameters.
/// e.g. RemoveFirstParameter_t<U<A,B>> is U<B>
template <typename>
struct RemoveFirstParameter {
};

template <typename T, template <typename...> class U, typename...Rest>
struct RemoveFirstParameter<U<T, Rest...>> {
   using type = U<Rest...>;
};

template <typename T>
using RemoveFirstParameter_t = typename RemoveFirstParameter<T>::type;

} // ns ROOT
} // ns TypeTraits
#endif //ROOT_TTypeTraits
<|endoftext|>


<commit_before>#include <string.h>
#include <stdlib.h>
#include <sstream>
#include <string>
#include "core/error.h"
#include "core/package/load.h"

using namespace ink;
using namespace std;

inline void
InkWarn_Unknown_Argument(Ink_InterpreteEngine *engine, const char *name)
{
	InkErro_doPrintWarning(engine, "Ink Packer: Unknown argument \"$(name)\"", name);
	return;
}

inline void
InkWarn_Excess_Argument(Ink_InterpreteEngine *engine, const char *name)
{
	InkErro_doPrintWarning(engine, "Ink Packer: Excess argument \"$(name)\"", name);
	return;
}

inline void
InkWarn_Unknown_Version(Ink_InterpreteEngine *engine, const char *name)
{
	InkErro_doPrintWarning(engine, "Ink Packer: Unknown version name \"$(name)\"", name);
	return;
}

inline void
InkError_Unknown_Version(Ink_InterpreteEngine *engine, const char *path)
{
	InkErro_doPrintError(engine, -1, "Ink Packer: Cannot detect module version of file $(path), please specify one", path);
	return;
}

inline void
InkError_No_Lib_Given(Ink_InterpreteEngine *engine)
{
	InkErro_doPrintError(engine, -1, "Ink Packer: No library file given");
	return;
}

inline void
InkError_No_Dest_Given(Ink_InterpreteEngine *engine)
{
	InkErro_doPrintError(engine, -1, "Ink Packer: No output file given");
	return;
}

inline void
InkError_Could_Not_Create_File(Ink_InterpreteEngine *engine, const char *path)
{
	stringstream strm;
	strm << "Ink Packer: Couldn't create file " << path;
	InkErro_doPrintError(engine, -1, strm.str().c_str());
	return;
}

enum Instr {
	UNKNOWN = 0,
	PACKAGE_NAME,
	AUTHOR,
	VERSION
};

class Argument {
public:
	Instr instr;
	char *arg;

	Argument(char *origin)
	{
		int i, len = strlen(origin), start;
		string instr_str;

		for (i = 0; i < len && origin[i] == '-'; i++) ;
		start = i;

		for (; i < len; i++) {
			if (origin[i] == '=') {
				break;
			}
		}

		arg = NULL;
		if (i < len) {
			instr_str = string(origin).substr(start, i - 2);
		} else {
			instr_str = string(origin).substr(start);
			return;
		}

		if (!strcmp(instr_str.c_str(), "package-name")) {
			instr = PACKAGE_NAME;
		} else if (!strcmp(instr_str.c_str(), "author")) {
			instr = AUTHOR;
		} else if (!strcmp(instr_str.c_str(), "version")) {
			instr = VERSION;
		} else {
			instr = UNKNOWN;
			InkWarn_Unknown_Argument(NULL, instr_str.c_str());
			return;
		}

		arg = (char *)malloc(sizeof(char) * (len - i));
		strcpy(arg, string(origin).substr(i + 1, len - i - 1).c_str());
	}

	~Argument()
	{
		if (arg)
			free(arg);
	}
};

#define MAX_ARG_COUNT 1000

Ink_MagicNumber getVersionBySuffix(char *path)
{
	auto i = strlen(path);

	if (i >= 3
		&& path[i - 1] == 'o'
		&& path[i - 2] == 's'
		&& path[i - 3] == '.') {
		return INK_MAGIC_NUM_0_LINUX;
	}

	if (i >= 4
		&& path[i - 1] == 'l'
		&& path[i - 2] == 'l'
		&& path[i - 3] == 'd'
		&& path[i = 4] == '.') {
		return INK_MAGIC_NUM_0_WINDOWS;
	}

	return INK_MAGIC_NUM_INVALID;
}

Ink_MagicNumber getVersionByName(char *name)
{
	if (!strcmp(name, "0_linux"))
		return INK_MAGIC_NUM_0_LINUX;
	else if (!strcmp(name, "0_win32"))
		return INK_MAGIC_NUM_0_WINDOWS;

	return INK_MAGIC_NUM_INVALID;
}

int main(int argc, char **argv)
{
	int i, argi = 0;
	const char *pack_name = "Unknown", *author = "Anonymous";
	char *dest = NULL;
	Argument *arg[MAX_ARG_COUNT];
	Ink_MagicNumber tmp_num;

	vector<Ink_MagicNumber> file_version = vector<Ink_MagicNumber>();
	vector<char *> files = vector<char *>();
	vector<char *>::size_type fi;

	for (i = 1; i < argc; i++) {
		if (argv[i][0] != '-') {
			files.push_back(argv[i]);
			file_version.push_back(INK_MAGIC_NUM_INVALID);
		} else {
			arg[argi++] = new Argument(argv[i]);
			if (arg[argi - 1]->instr == VERSION) {
				tmp_num = getVersionByName(arg[argi - 1]->arg);
				if (tmp_num == INK_MAGIC_NUM_INVALID) {
					InkWarn_Unknown_Version(NULL, arg[argi - 1]->arg);
				} else {
					file_version[file_version.size() - 1] = tmp_num;
				}
			}
		}
	}

	for (i = 0; i < argi; i++) {
		if (arg[i]->instr == PACKAGE_NAME) {
			pack_name = arg[i]->arg;
		} else if (arg[i]->instr == AUTHOR) {
			author = arg[i]->arg;
		}
	}

	if (!files.size()) {
		InkError_No_Lib_Given(NULL);
		// unreachable
	}

	if (files.size() <= 1) {
		InkError_No_Dest_Given(NULL);
		// unreachable
	}

	dest = files[files.size() - 1];

	FILE *fp;
	fp = fopen(dest, "wb");

	if (!fp) {
		InkError_Could_Not_Create_File(NULL, dest);
		// unreachable
	}

	Ink_Package *pack = new Ink_Package(pack_name, author);

	for (fi = 0; fi < files.size() - 1; fi++) {
		tmp_num = file_version[fi] == INK_MAGIC_NUM_INVALID
				  ? getVersionBySuffix(files[fi])
				  : file_version[fi];
		if (tmp_num == INK_MAGIC_NUM_INVALID) {
			InkError_Unknown_Version(NULL, files[fi]);
			// unreachable
		}
		pack->addDLFile(files[fi], tmp_num);
	}

	pack->writeTo(fp);
	fflush(fp);
	fclose(fp);

	return 0;
}
<commit_msg>090216#02: add usage printing in ink-packer<commit_after>#include <string.h>
#include <stdlib.h>
#include <sstream>
#include <string>
#include "core/error.h"
#include "core/package/load.h"

using namespace ink;
using namespace std;

inline void
InkWarn_Unknown_Argument(Ink_InterpreteEngine *engine, const char *name)
{
	InkErro_doPrintWarning(engine, "Ink Packer: Unknown argument \"$(name)\"", name);
	return;
}

inline void
InkWarn_Excess_Argument(Ink_InterpreteEngine *engine, const char *name)
{
	InkErro_doPrintWarning(engine, "Ink Packer: Excess argument \"$(name)\"", name);
	return;
}

inline void
InkWarn_Unknown_Version(Ink_InterpreteEngine *engine, const char *name)
{
	InkErro_doPrintWarning(engine, "Ink Packer: Unknown version name \"$(name)\"", name);
	return;
}

inline void
InkError_Unknown_Version(Ink_InterpreteEngine *engine, const char *path)
{
	InkErro_doPrintError(engine, -1, "Ink Packer: Cannot detect module version of file $(path), please specify one", path);
	return;
}

inline void
InkError_No_Lib_Given(Ink_InterpreteEngine *engine)
{
	InkErro_doPrintError(engine, -1, "Ink Packer: No library file given");
	return;
}

inline void
InkError_No_Dest_Given(Ink_InterpreteEngine *engine)
{
	InkErro_doPrintError(engine, -1, "Ink Packer: No output file given");
	return;
}

inline void
InkError_Could_Not_Create_File(Ink_InterpreteEngine *engine, const char *path)
{
	stringstream strm;
	strm << "Ink Packer: Couldn't create file " << path;
	InkErro_doPrintError(engine, -1, strm.str().c_str());
	return;
}

enum Instr {
	UNKNOWN = 0,
	PACKAGE_NAME,
	AUTHOR,
	VERSION
};

class Argument {
public:
	Instr instr;
	char *arg;

	Argument(char *origin)
	{
		int i, len = strlen(origin), start;
		string instr_str;

		for (i = 0; i < len && origin[i] == '-'; i++) ;
		start = i;

		for (; i < len; i++) {
			if (origin[i] == '=') {
				break;
			}
		}

		arg = NULL;
		if (i < len) {
			instr_str = string(origin).substr(start, i - 2);
		} else {
			instr_str = string(origin).substr(start);
			return;
		}

		if (!strcmp(instr_str.c_str(), "package-name")) {
			instr = PACKAGE_NAME;
		} else if (!strcmp(instr_str.c_str(), "author")) {
			instr = AUTHOR;
		} else if (!strcmp(instr_str.c_str(), "version")) {
			instr = VERSION;
		} else {
			instr = UNKNOWN;
			InkWarn_Unknown_Argument(NULL, instr_str.c_str());
			return;
		}

		arg = (char *)malloc(sizeof(char) * (len - i));
		strcpy(arg, string(origin).substr(i + 1, len - i - 1).c_str());
	}

	~Argument()
	{
		if (arg)
			free(arg);
	}
};

#define MAX_ARG_COUNT 1000

Ink_MagicNumber getVersionBySuffix(char *path)
{
	auto i = strlen(path);

	if (i >= 3
		&& path[i - 1] == 'o'
		&& path[i - 2] == 's'
		&& path[i - 3] == '.') {
		return INK_MAGIC_NUM_0_LINUX;
	}

	if (i >= 4
		&& path[i - 1] == 'l'
		&& path[i - 2] == 'l'
		&& path[i - 3] == 'd'
		&& path[i = 4] == '.') {
		return INK_MAGIC_NUM_0_WINDOWS;
	}

	return INK_MAGIC_NUM_INVALID;
}

Ink_MagicNumber getVersionByName(char *name)
{
	if (!strcmp(name, "0_linux"))
		return INK_MAGIC_NUM_0_LINUX;
	else if (!strcmp(name, "0_win32"))
		return INK_MAGIC_NUM_0_WINDOWS;

	return INK_MAGIC_NUM_INVALID;
}

void printUsage(char *path)
{
	fprintf(stderr, "Usage: %s [--package-name=<name>] [--author=<name>] <dynamic lib path> [[--version=<0_linux|0_win32>] <dynamic lib path>...] <dest file>\n",
			path);
}

int main(int argc, char **argv)
{
	int i, argi = 0;
	const char *pack_name = "Unknown", *author = "Anonymous";
	char *dest = NULL;
	Argument *arg[MAX_ARG_COUNT];
	Ink_MagicNumber tmp_num;

	vector<Ink_MagicNumber> file_version = vector<Ink_MagicNumber>();
	vector<char *> files = vector<char *>();
	vector<char *>::size_type fi;

	if (argc <= 1) {
		printUsage(argv[0]);
		return 0;
	}

	for (i = 1; i < argc; i++) {
		if (argv[i][0] != '-') {
			files.push_back(argv[i]);
			file_version.push_back(INK_MAGIC_NUM_INVALID);
		} else {
			arg[argi++] = new Argument(argv[i]);
			if (arg[argi - 1]->instr == VERSION) {
				tmp_num = getVersionByName(arg[argi - 1]->arg);
				if (tmp_num == INK_MAGIC_NUM_INVALID) {
					InkWarn_Unknown_Version(NULL, arg[argi - 1]->arg);
				} else {
					file_version[file_version.size() - 1] = tmp_num;
				}
			}
		}
	}

	for (i = 0; i < argi; i++) {
		if (arg[i]->instr == PACKAGE_NAME) {
			pack_name = arg[i]->arg;
		} else if (arg[i]->instr == AUTHOR) {
			author = arg[i]->arg;
		}
	}

	if (!files.size()) {
		printUsage(argv[0]);
		InkError_No_Lib_Given(NULL);
		// unreachable
	}

	if (files.size() <= 1) {
		printUsage(argv[0]);
		InkError_No_Dest_Given(NULL);
		// unreachable
	}

	dest = files[files.size() - 1];

	FILE *fp;
	fp = fopen(dest, "wb");

	if (!fp) {
		printUsage(argv[0]);
		InkError_Could_Not_Create_File(NULL, dest);
		// unreachable
	}

	Ink_Package *pack = new Ink_Package(pack_name, author);

	for (fi = 0; fi < files.size() - 1; fi++) {
		tmp_num = file_version[fi] == INK_MAGIC_NUM_INVALID
				  ? getVersionBySuffix(files[fi])
				  : file_version[fi];
		if (tmp_num == INK_MAGIC_NUM_INVALID) {
			printUsage(argv[0]);
			InkError_Unknown_Version(NULL, files[fi]);
			// unreachable
		}
		pack->addDLFile(files[fi], tmp_num);
	}

	pack->writeTo(fp);
	fflush(fp);
	fclose(fp);

	return 0;
}
<|endoftext|>


<commit_before>#include <stdlib.h>
#include "vtrc-call-context.h"

namespace vtrc { namespace common {

    typedef vtrc_rpc_lowlevel::lowlevel_unit lowlevel_unit;

    struct call_context::impl {
        lowlevel_unit *llu_;
        const vtrc_rpc_lowlevel::options *opts_;
        impl( )
            :opts_(NULL)
        { }
    };

    call_context::call_context( lowlevel_unit *lowlevel )
        :impl_(new impl)
    {
        impl_->llu_ = lowlevel;
    }

    call_context::call_context( const call_context &other )
        :impl_(new impl(*other.impl_))
    {}

    call_context &call_context::operator = ( const call_context &other )
    {
        *impl_ = *other.impl_;
        return *this;
    }

    const lowlevel_unit *call_context::get_lowlevel_message( ) const
    {
        return impl_->llu_;
    }

    lowlevel_unit *call_context::get_lowlevel_message( )
    {
        return impl_->llu_;
    }

    const vtrc_rpc_lowlevel::options *call_context::get_call_options( ) const
    {
        impl_->opts_;
    }

    void call_context::set_call_options(const vtrc_rpc_lowlevel::options &opts)
    {
        impl_->opts_ = &opts;
    }

    call_context::~call_context( )
    {
        delete impl_;
    }

}}

<commit_msg>protocol<commit_after>#include <stdlib.h>
#include "vtrc-call-context.h"

namespace vtrc { namespace common {

    typedef vtrc_rpc_lowlevel::lowlevel_unit lowlevel_unit;

    struct call_context::impl {
        lowlevel_unit *llu_;
        const vtrc_rpc_lowlevel::options *opts_;
        impl( )
            :opts_(NULL)
        { }
    };

    call_context::call_context( lowlevel_unit *lowlevel )
        :impl_(new impl)
    {
        impl_->llu_ = lowlevel;
    }

    call_context::call_context( const call_context &other )
        :impl_(new impl(*other.impl_))
    {}

    call_context &call_context::operator = ( const call_context &other )
    {
        *impl_ = *other.impl_;
        return *this;
    }

    const lowlevel_unit *call_context::get_lowlevel_message( ) const
    {
        return impl_->llu_;
    }

    lowlevel_unit *call_context::get_lowlevel_message( )
    {
        return impl_->llu_;
    }

    const vtrc_rpc_lowlevel::options *call_context::get_call_options( ) const
    {
        return impl_->opts_;
    }

    void call_context::set_call_options(const vtrc_rpc_lowlevel::options &opts)
    {
        impl_->opts_ = &opts;
    }

    call_context::~call_context( )
    {
        delete impl_;
    }

}}

<|endoftext|>