<commit_before>#pragma once
//=====================================================================//
/*!	@file
	@brief	Arithmetic テンプレート @n
			※テキストの数式を展開して、計算結果を得る。@n
			演算式解析
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2015, 2020 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/R8C/blob/master/LICENSE
*/
//=====================================================================//
#include <cstdint>
#include "common/bitset.hpp"

namespace utils {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief	Arithmetic クラス
		@param[in]	VTYPE	基本型
		@param[in]	SYMBOL	シンボルクラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template <typename VTYPE>
	struct basic_arith {

		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		/*!
			@brief	エラー・タイプ
		*/
		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		enum class error : uint8_t {
			fatal,				///< エラー
			number_fatal,		///< 数字の変換に関するエラー
			zero_divide,		///< ０除算エラー
			binary_fatal,		///< ２進データの変換に関するエラー
			octal_fatal,		///< ８進データの変換に関するエラー
			hexdecimal_fatal,	///< １６進データの変換に関するエラー
			num_fatal,			///< 数値の変換に関するエラー
			symbol_fatal,		///< シンボルデータの変換に関するエラー
		};

		typedef bitset<uint16_t, error> error_t;

	private:

		const char*		tx_;
		char			ch_;

		error_t		error_;

		VTYPE		value_;

		void skip_space_() {
			while(ch_ == ' ' || ch_ == '\t') {
				ch_ = *tx_++;
			}
		}

		VTYPE number_() {
			bool inv = false;
///			bool neg = false;
			bool point = false;
			int32_t v = 0;
			uint32_t fp = 0;
			uint32_t fs = 1;

			skip_space_();

			// 符号、反転の判定
			if(ch_ == '-') {
				inv = true;
				ch_ = *tx_++;
			} else if(ch_ == '+') {
				ch_ = *tx_++;
//			} else if(ch_ == '!' || ch_ == '~') {
//				neg = true;
//				ch_ = *tx_++;
			}

			skip_space_();

			if(ch_ == '(') {
				v = factor_();
			} else {
				skip_space_();

//				if(ch_ >= 'A' && ch_ <= 'Z') symbol = true;
//				else if(ch_ >= 'a' && ch_ <= 'z') symbol = true;
//				else if(ch_ == '_' || ch_ == '?') symbol = true;

				while(ch_ != 0) {
					if(ch_ == '+') break;
					else if(ch_ == '-') break;
					else if(ch_ == '*') break;
					else if(ch_ == '/') break;
//					else if(ch_ == '&') break;
//					else if(ch_ == '^') break;
//					else if(ch_ == '|') break;
//					else if(ch_ == '%') break;
					else if(ch_ == ')') break;
//					else if(ch_ == '<') break;
//					else if(ch_ == '>') break;
//					else if(ch_ == '!') break;
//					else if(ch_ == '~') break;
					else if(ch_ == '.') {
						if(point) {
							error_.set(error::fatal);
							break;
						} else {
							point = true;
						}
					} else if(ch_ >= '0' && ch_ <= '9') {
						if(point) {
							fp *= 10;
							fp += ch_ - '0';
							fs *= 10;
						} else {
							v *= 10;
							v += ch_ - '0';
						}
					}
					ch_ = *tx_++;
				}

#if 0
				if(symbol) {
					symbol_map_cit cit = symbol_.find(sym);
					if(cit != symbol_.end()) {
						v = (*cit).second;
					} else {
						error_.set(error::symbol_fatal);
					}
				}
#endif
			}

			if(inv) { v = -v; }
///			if(neg) { v = ~v; }
			if(point) {
				return static_cast<VTYPE>(v) + static_cast<VTYPE>(fp) / static_cast<VTYPE>(fs);
			} else {
				return static_cast<VTYPE>(v);
			}
		}

		VTYPE factor_() {
			VTYPE v = 0;
			if(ch_ == '(') {
				ch_ = *tx_++;
				v = expression_();
				if(ch_ == ')') {
					ch_ = *tx_++;
				} else {
					error_.set(error::fatal);
				}
			} else {
				v = number_();
			}
			return v;
		}

		VTYPE term_() {
			VTYPE v = factor_();
			VTYPE tmp;
			while(error_() == 0) {
				switch(ch_) {
				case ' ':
				case '\t':
					ch_ = *tx_++;
					break;
				case '*':
					ch_ = *tx_++;
					v *= factor_();
					break;
#if 0
				case '%':
					ch_ = *tx_++;
					tmp = factor_();
					if(tmp == 0) {
						error_.set(error::zero_divide);
						break;
					}
					v %= tmp;
					break;
#endif
				case '/':
					ch_ = *tx_++;
					if(ch_ == '/') {
						ch_ = *tx_++;
						tmp = factor_();
						if(tmp == 0) {
							error_.set(error::zero_divide);
							break;
						}
///						v %= tmp;
					} else {
						tmp = factor_();
						if(tmp == 0) {
							error_.set(error::zero_divide);
							break;
						}
						v /= tmp;
					}
					break;
#if 0
				case '<':
					ch_ = *tx_++;
					if(ch_ == '<') {
						ch_ = *tx_++;
						v <<= factor_();
					} else {
						error_.set(error::fatal);
					}
					break;
				case '>':
					ch_ = *tx_++;
					if(ch_ == '>') {
						ch_ = *tx_++;
						v <<= factor_();
					} else {
						error_.set(error::fatal);
					}
					break;
#endif
				default:
					return v;
					break;
				}
			}
			return v;
		}

		VTYPE expression_() {
			VTYPE v = term_();
			while(error_() == 0) {
				switch(ch_) {
				case ' ':
				case '\t':
					ch_ = *tx_++;
					break;
				case '+':
					ch_ = *tx_++;
					v += term_();
					break;
				case '-':
					ch_ = *tx_++;
					v -= term_();
					break;
#if 0
				case '&':
					ch_ = *tx_++;
					v &= term_();
					break;
				case '^':
					ch_ = *tx_++;
					v ^= term_();
					break;
				case '|':
					ch_ = *tx_++;
					v |= term_();
					break;
#endif
				default:
					return v;
					break;
				}
			}
			return v;
		}

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief	コンストラクター
		*/
		//-----------------------------------------------------------------//
		basic_arith() : tx_(nullptr), ch_(0), error_(), value_(0) { }

		//-----------------------------------------------------------------//
		/*!
			@brief	解析を開始
			@param[in]	text	解析テキスト
			@return	文法にエラーがあった場合、「false」
		*/
		//-----------------------------------------------------------------//
		bool analize(const char* text) {
			if(text == nullptr) {
				error_.set(error::fatal);
				return false;
			}
			tx_ = text;

			error_.clear();

			ch_ = *tx_++;
			if(ch_ != 0) {
				value_ = expression_();
			} else {
				error_.set(error::fatal);
			}

			if(error_() != 0) {
				return false;
			} else if(ch_ != 0) {
				error_.set(error::fatal);
				return false;
			}
			return true;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	エラーを受け取る
			@return エラー
		*/
		//-----------------------------------------------------------------//
		const error_t& get_error() const { return error_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	結果を取得
			@return	結果
		*/
		//-----------------------------------------------------------------//
		VTYPE get() const { return value_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	() で結果を取得
			@return	結果
		*/
		//-----------------------------------------------------------------//
		VTYPE operator() () const { return value_; }
	};
}
<commit_msg>Update: cleanup<commit_after>#pragma once
//=====================================================================//
/*!	@file
	@brief	Arithmetic テンプレート @n
			※テキストの数式を展開して、計算結果を得る。@n
			NVAL には、Boost Multiprecision Library を利用する事を前提にしている。
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2015, 2020 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include <cstdint>
#include "common/bitset.hpp"

namespace utils {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief	Arithmetic クラス
		@param[in]	NVAL	基本型
		@param[in]	SYMBOL	変数クラス
		@param[in]	FUNC	関数クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template <class NVAL, class SYMBOL, class FUNC>
	struct basic_arith {

		static const uint32_t NUMBER_NUM = 50;  // 最大桁数

		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		/*!
			@brief	エラー・タイプ
		*/
		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		enum class error : uint8_t {
			fatal,				///< エラー
			number_fatal,		///< 数字の変換に関するエラー
			zero_divide,		///< ０除算エラー
			binary_fatal,		///< ２進データの変換に関するエラー
			octal_fatal,		///< ８進データの変換に関するエラー
			hexdecimal_fatal,	///< １６進データの変換に関するエラー
			num_fatal,			///< 数値の変換に関するエラー
			symbol_fatal,		///< シンボルデータの変換に関するエラー
			func_fatal,			///< 関数の変換に関するエラー
		};

		typedef bitset<uint16_t, error> error_t;

	private:

		SYMBOL&		symbol_;
		FUNC&		func_;

		const char*		tx_;
		char			ch_;

		error_t		error_;

		NVAL		value_;

		// スペース、TAB を取り除く
		void skip_space_() noexcept
		{
			while(ch_ == ' ' || ch_ == '\t') {
				ch_ = *tx_++;
			}
		}

		// 関数内パラメーターの取得
		bool param_(char* dst, uint32_t len)
		{
			if(ch_ != '(') return false;

			while(ch_ != 0) {
				--len;
				if(len == 0) break;
			}

			return true;
		}

		NVAL number_()
		{
			bool minus = false;
			char tmp[NUMBER_NUM];

			skip_space_();

			// 符号、反転の判定
			if(ch_ == '-') {
				minus = true;
				ch_ = *tx_++;
			} else if(ch_ == '+') {
				ch_ = *tx_++;
			}

			skip_space_();

			NVAL nval;
			if(static_cast<uint8_t>(ch_) >= 0x80) {  // symbol?, func?
				if(static_cast<uint8_t>(ch_) >= 0xC0) {  // func ?
					auto fc = static_cast<typename FUNC::NAME>(ch_);
					ch_ = *tx_++;
					if(ch_ == '(') {
						ch_ = *tx_++;
						auto param = expression_();
						if(ch_ == ')') {
							ch_ = *tx_++;
							if(!func_(fc, param, nval)) {
								error_.set(error::func_fatal);
							}
						} else {
							error_.set(error::fatal);
						}
					} else {
						error_.set(error::func_fatal);
					}
				} else {  // to symbol
					if(symbol_(static_cast<typename SYMBOL::NAME>(ch_), nval)) {
						ch_ = *tx_++;
					} else {
						error_.set(error::symbol_fatal);
					}
				}
				return nval;
			}

			if(ch_ == '(') {
				nval = factor_();
			} else {
				uint32_t idx = 0;
				while(ch_ != 0) {
					if(ch_ == '+') break;
					else if(ch_ == '-') break;
					else if(ch_ == '*') break;
					else if(ch_ == '/') break;
					else if(ch_ == ')') break;
					else if((ch_ >= '0' && ch_ <= '9') || ch_=='.' || ch_=='e' || ch_=='E') {
						tmp[idx] = ch_;
						idx++;
					} else {
						error_.set(error::fatal);
						break;
					}
					ch_ = *tx_++;
				}
				tmp[idx] = 0;
				if(error_() == 0) {
					nval.assign(tmp);
				}
			}

			if(minus) { nval = -nval; }

			return nval;
		}

		auto factor_()
		{
			NVAL v(0.0);
			if(ch_ == '(') {
				ch_ = *tx_++;
				v = expression_();
				if(ch_ == ')') {
					ch_ = *tx_++;
				} else {
					error_.set(error::fatal);
				}
			} else {
				v = number_();
			}
			return v;
		}

		NVAL term_() {
			NVAL v = factor_();
			NVAL tmp;
			while(error_() == 0) {
				switch(ch_) {
				case ' ':
				case '\t':
					ch_ = *tx_++;
					break;
				case '*':
					ch_ = *tx_++;
					v *= factor_();
					break;
#if 0
				case '%':
					ch_ = *tx_++;
					tmp = factor_();
					if(tmp == 0) {
						error_.set(error::zero_divide);
						break;
					}
					v %= tmp;
					break;
#endif
				case '/':
					ch_ = *tx_++;
					if(ch_ == '/') {
						ch_ = *tx_++;
						tmp = factor_();
						if(tmp == 0) {
							error_.set(error::zero_divide);
							break;
						}
					} else {
						tmp = factor_();
						if(tmp == 0) {
							error_.set(error::zero_divide);
							break;
						}
						v /= tmp;
					}
					break;
#if 0
				case '<':
					ch_ = *tx_++;
					if(ch_ == '<') {
						ch_ = *tx_++;
						v <<= factor_();
					} else {
						error_.set(error::fatal);
					}
					break;
				case '>':
					ch_ = *tx_++;
					if(ch_ == '>') {
						ch_ = *tx_++;
						v <<= factor_();
					} else {
						error_.set(error::fatal);
					}
					break;
#endif
				default:
					return v;
					break;
				}
			}
			return v;
		}

		NVAL expression_() {
			NVAL v = term_();
			while(error_() == 0) {
				switch(ch_) {
				case ' ':
				case '\t':
					ch_ = *tx_++;
					break;
				case '+':
					ch_ = *tx_++;
					v += term_();
					break;
				case '-':
					ch_ = *tx_++;
					v -= term_();
					break;
#if 0
				case '&':
					ch_ = *tx_++;
					v &= term_();
					break;
				case '^':
					ch_ = *tx_++;
					v ^= term_();
					break;
				case '|':
					ch_ = *tx_++;
					v |= term_();
					break;
#endif
				default:
					return v;
					break;
				}
			}
			return v;
		}

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief	コンストラクター
			@param[in]	func	関数クラス
		*/
		//-----------------------------------------------------------------//
		basic_arith(SYMBOL& symbol, FUNC& func) noexcept : symbol_(symbol), func_(func),
			tx_(nullptr), ch_(0), error_(), value_()
		{ }

		//-----------------------------------------------------------------//
		/*!
			@brief	解析を開始
			@param[in]	text	解析テキスト
			@return	文法にエラーがあった場合、「false」
		*/
		//-----------------------------------------------------------------//
		bool analize(const char* text)
		{
			if(text == nullptr) {
				error_.set(error::fatal);
				return false;
			}
			tx_ = text;

			error_.clear();

			ch_ = *tx_++;
			if(ch_ != 0) {
				value_ = expression_();
			} else {
				error_.set(error::fatal);
			}

			if(error_() != 0) {
				return false;
			} else if(ch_ != 0) {
				error_.set(error::fatal);
				return false;
			}
			return true;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	エラーを受け取る
			@return エラー
		*/
		//-----------------------------------------------------------------//
		const error_t& get_error() const { return error_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	エラーメッセージを取得
			@return エラーメッセージ
		*/
		//-----------------------------------------------------------------//
		template <class STR>
		STR get_error() const {
			STR str;
			return str;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	埋め込まれた、シンボル、関数名を展開
			@param[in]	in		入力文字列
			@param[out]	out		展開文字列
			@param[in]	len		展開文字列サイズ
			@return	成功なら「true」
		*/
		//-----------------------------------------------------------------//
		bool parse(const char* in, char* out, uint32_t len) const
		{
			char ch;
			while(len > 1 && (ch = *in++) != 0) {
				uint8_t n = static_cast<uint8_t>(ch);
				if(n < 0x80) {
					*out++ = ch;
					len--;
				} else if(n < 0xc0) {  // シンボル

				} else {  // 関数

				}
			}
			*out = 0;
			return len > 1;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	() で結果を取得
			@return	結果
		*/
		//-----------------------------------------------------------------//
		NVAL operator() () const { return value_; }
	};
}
<|endoftext|>


<commit_before>// Copyright 2021 MozoLM Authors.
//
// 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 "mozolm/models/language_model.h"

#include <algorithm>

#include "ngram/ngram-model.h"
#include "absl/strings/str_cat.h"
#include "nisaba/port/utf8_util.h"

namespace mozolm {
namespace models {

int LanguageModel::ContextState(const std::string& context, int init_state) {
  int this_state = init_state < 0 ? start_state_ : init_state;
  if (!context.empty()) {
    const std::vector<int> context_utf8 =
        nisaba::utf8::StrSplitByCharToUnicode(context);
    for (const auto& sym : context_utf8) {
      this_state = NextState(this_state, static_cast<int>(sym));
      if (this_state < 0) {
        // Returns to start state if symbol not found.
        // TODO: should it return to a null context state?
        this_state = start_state_;
      }
    }
  }
  return this_state;
}

absl::StatusOr<std::vector<std::pair<double, std::string>>>
GetTopHypotheses(const LMScores &scores, int top_n) {
  const int num_entries = scores.probabilities().size();
  if (num_entries != scores.symbols().size()) {
    return absl::InternalError(absl::StrCat(
        "Mismatching number of probabilities (", num_entries,
        ") and symbols (", scores.symbols().size(), ")"));
  }
  if (num_entries <= top_n) {
    return absl::InternalError(absl::StrCat(
        "Too many candidates requested: ", top_n));
  } else if (num_entries == 0) {
    return absl::InternalError("No scores to return");
  }
  std::vector<std::pair<double, std::string>> hyps;
  hyps.reserve(num_entries);
  for (int i = 0; i < num_entries; ++i) {
    hyps.push_back({ scores.probabilities(i), scores.symbols(i) });
  }
  std::sort(hyps.begin(), hyps.end(),
            [](const std::pair<double, std::string> &a,
               const std::pair<double, std::string> &b) {
              return a.first > b.first;
            });
  if (top_n > 0) {
    hyps = std::vector(hyps.begin(), hyps.begin() + top_n);
  }
  return std::move(hyps);
}

void SoftmaxRenormalize(std::vector<double> *neg_log_probs) {
  double tot_prob = (*neg_log_probs)[0];
  double kahan_factor = 0.0;
  for (int i = 1; i < neg_log_probs->size(); ++i) {
    tot_prob =
        ngram::NegLogSum(tot_prob, (*neg_log_probs)[i], &kahan_factor);
  }
  for (int i = 0; i < neg_log_probs->size(); ++i) {
    (*neg_log_probs)[i] -= tot_prob;
  }
}

}  // namespace models
}  // namespace mozolm
<commit_msg>Cosmetic change: Getting rid of silly no-op static cast.<commit_after>// Copyright 2021 MozoLM Authors.
//
// 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 "mozolm/models/language_model.h"

#include <algorithm>

#include "ngram/ngram-model.h"
#include "absl/strings/str_cat.h"
#include "nisaba/port/utf8_util.h"

namespace mozolm {
namespace models {

int LanguageModel::ContextState(const std::string& context, int init_state) {
  int this_state = init_state < 0 ? start_state_ : init_state;
  if (!context.empty()) {
    const std::vector<int> context_utf8 =
        nisaba::utf8::StrSplitByCharToUnicode(context);
    for (auto sym : context_utf8) {
      this_state = NextState(this_state, sym);
      if (this_state < 0) {
        // Returns to start state if symbol not found.
        // TODO: should it return to a null context state?
        this_state = start_state_;
      }
    }
  }
  return this_state;
}

absl::StatusOr<std::vector<std::pair<double, std::string>>>
GetTopHypotheses(const LMScores &scores, int top_n) {
  const int num_entries = scores.probabilities().size();
  if (num_entries != scores.symbols().size()) {
    return absl::InternalError(absl::StrCat(
        "Mismatching number of probabilities (", num_entries,
        ") and symbols (", scores.symbols().size(), ")"));
  }
  if (num_entries <= top_n) {
    return absl::InternalError(absl::StrCat(
        "Too many candidates requested: ", top_n));
  } else if (num_entries == 0) {
    return absl::InternalError("No scores to return");
  }
  std::vector<std::pair<double, std::string>> hyps;
  hyps.reserve(num_entries);
  for (int i = 0; i < num_entries; ++i) {
    hyps.push_back({ scores.probabilities(i), scores.symbols(i) });
  }
  std::sort(hyps.begin(), hyps.end(),
            [](const std::pair<double, std::string> &a,
               const std::pair<double, std::string> &b) {
              return a.first > b.first;
            });
  if (top_n > 0) {
    hyps = std::vector(hyps.begin(), hyps.begin() + top_n);
  }
  return std::move(hyps);
}

void SoftmaxRenormalize(std::vector<double> *neg_log_probs) {
  double tot_prob = (*neg_log_probs)[0];
  double kahan_factor = 0.0;
  for (int i = 1; i < neg_log_probs->size(); ++i) {
    tot_prob =
        ngram::NegLogSum(tot_prob, (*neg_log_probs)[i], &kahan_factor);
  }
  for (int i = 0; i < neg_log_probs->size(); ++i) {
    (*neg_log_probs)[i] -= tot_prob;
  }
}

}  // namespace models
}  // namespace mozolm
<|endoftext|>


<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/common/set_process_title.h"

#include "base/command_line.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/string_util.h"
#include "build/build_config.h"

#if defined(OS_POSIX)
#include <limits.h>
#include <stdlib.h>
#include <unistd.h>
#endif

#if defined(OS_LINUX)
#include <sys/prctl.h>

// Linux/glibc doesn't natively have setproctitle().
#include "content/common/set_process_title_linux.h"
#endif

#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_SOLARIS) && \
    defined(OS_OPENBSD)

void SetProcessTitleFromCommandLine(const char** main_argv) {
  // Build a single string which consists of all the arguments separated
  // by spaces. We can't actually keep them separate due to the way the
  // setproctitle() function works.
  std::string title;
  bool have_argv0 = false;

#if defined(OS_LINUX)
  if (main_argv)
    setproctitle_init(main_argv);

  // In Linux we sometimes exec ourselves from /proc/self/exe, but this makes us
  // show up as "exe" in process listings. Read the symlink /proc/self/exe and
  // use the path it points at for our process title. Note that this is only for
  // display purposes and has no TOCTTOU security implications.
  FilePath target;
  FilePath self_exe("/proc/self/exe");
  if (file_util::ReadSymbolicLink(self_exe, &target)) {
    have_argv0 = true;
    title = target.value();
    // If the binary has since been deleted, Linux appends " (deleted)" to the
    // symlink target. Remove it, since this is not really part of our name.
    const std::string kDeletedSuffix = " (deleted)";
    if (EndsWith(title, kDeletedSuffix, true))
      title.resize(title.size() - kDeletedSuffix.size());
#if defined(PR_SET_NAME)
    // If PR_SET_NAME is available at compile time, we try using it. We ignore
    // any errors if the kernel does not support it at runtime though. When
    // available, this lets us set the short process name that shows when the
    // full command line is not being displayed in most process listings.
    prctl(PR_SET_NAME, FilePath(title).BaseName().value().c_str());
#endif
  }
#endif

  const CommandLine* command_line = CommandLine::ForCurrentProcess();
  for (size_t i = 1; i < command_line->argv().size(); ++i) {
    if (!title.empty())
      title += " ";
    title += command_line->argv()[i];
  }
  // Disable prepending argv[0] with '-' if we prepended it ourselves above.
  setproctitle(have_argv0 ? "-%s" : "%s", title.c_str());
}

#else

// All other systems (basically Windows & Mac) have no need or way to implement
// this function.
void SetProcessTitleFromCommandLine(const char** /* main_argv */) {
}

#endif

<commit_msg>Linux: Fix bad #define for SetProcessTitleFromCommandLine().<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/common/set_process_title.h"

#include "build/build_config.h"

#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_SOLARIS)
#include <limits.h>
#include <stdlib.h>
#include <unistd.h>

#include <string>

#include "base/command_line.h"
#endif  // defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_SOLARIS)

#if defined(OS_LINUX)
#include <sys/prctl.h>

#include "base/file_path.h"
#include "base/file_util.h"
#include "base/string_util.h"
// Linux/glibc doesn't natively have setproctitle().
#include "content/common/set_process_title_linux.h"
#endif  // defined(OS_LINUX)

#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_SOLARIS)

void SetProcessTitleFromCommandLine(const char** main_argv) {
  // Build a single string which consists of all the arguments separated
  // by spaces. We can't actually keep them separate due to the way the
  // setproctitle() function works.
  std::string title;
  bool have_argv0 = false;

#if defined(OS_LINUX)
  if (main_argv)
    setproctitle_init(main_argv);

  // In Linux we sometimes exec ourselves from /proc/self/exe, but this makes us
  // show up as "exe" in process listings. Read the symlink /proc/self/exe and
  // use the path it points at for our process title. Note that this is only for
  // display purposes and has no TOCTTOU security implications.
  FilePath target;
  FilePath self_exe("/proc/self/exe");
  if (file_util::ReadSymbolicLink(self_exe, &target)) {
    have_argv0 = true;
    title = target.value();
    // If the binary has since been deleted, Linux appends " (deleted)" to the
    // symlink target. Remove it, since this is not really part of our name.
    const std::string kDeletedSuffix = " (deleted)";
    if (EndsWith(title, kDeletedSuffix, true))
      title.resize(title.size() - kDeletedSuffix.size());
#if defined(PR_SET_NAME)
    // If PR_SET_NAME is available at compile time, we try using it. We ignore
    // any errors if the kernel does not support it at runtime though. When
    // available, this lets us set the short process name that shows when the
    // full command line is not being displayed in most process listings.
    prctl(PR_SET_NAME, FilePath(title).BaseName().value().c_str());
#endif  // defined(PR_SET_NAME)
  }
#endif  // defined(OS_LINUX)

  const CommandLine* command_line = CommandLine::ForCurrentProcess();
  for (size_t i = 1; i < command_line->argv().size(); ++i) {
    if (!title.empty())
      title += " ";
    title += command_line->argv()[i];
  }
  // Disable prepending argv[0] with '-' if we prepended it ourselves above.
  setproctitle(have_argv0 ? "-%s" : "%s", title.c_str());
}

#else

// All other systems (basically Windows & Mac) have no need or way to implement
// this function.
void SetProcessTitleFromCommandLine(const char** /* main_argv */) {
}

#endif
<|endoftext|>


<commit_before>#ifndef VIENNAGRID_METAINFO_HPP
#define VIENNAGRID_METAINFO_HPP

/* =======================================================================
   Copyright (c) 2011-2012, Institute for Microelectronics,
                            Institute for Analysis and Scientific Computing,
                            TU Wien.

                            -----------------
                     ViennaGrid - The Vienna Grid Library
                            -----------------

   Authors:      Karl Rupp                           rupp@iue.tuwien.ac.at
                 Josef Weinbub                    weinbub@iue.tuwien.ac.at

   (A list of additional contributors can be found in the PDF manual)

   License:      MIT (X11), see file LICENSE in the base directory
======================================================================= */

namespace viennagrid
{

    namespace metainfo
    {

        struct random_access_tag {};
        struct associative_access_tag {};

        namespace result_of
        {

            template<typename container_type>
            struct associative_container_value_type
            {
                typedef typename container_type::value_type type;
            };

            template<typename key_type, typename value_type, typename compare, typename allocator>
            struct associative_container_value_type< std::map<key_type, value_type, compare, allocator> >
            {
                typedef value_type type;
            };

            template<typename container_type>
            struct associative_container_access_tag
            {
                typedef random_access_tag type;
            };

            template<typename key_type, typename value_type, typename compare, typename allocator>
            struct associative_container_access_tag< std::map<key_type, value_type, compare, allocator> >
            {
                typedef associative_access_tag type;
            };

        }

        template<typename geometric_container_type, typename element_type>
        typename result_of::associative_container_value_type<geometric_container_type>::type & look_up( geometric_container_type & container, const element_type & element, random_access_tag )
        {
            return container[ element.id().get() ];
        }

        template<typename geometric_container_type, typename element_type>
        typename result_of::associative_container_value_type<geometric_container_type>::type & look_up( geometric_container_type & container, const element_type & element, associative_access_tag )
        {
            typename geometric_container_type::iterator it = container.find( element.id() );
            return it->second;
        }

        template<typename geometric_container_type, typename element_type>
        typename result_of::associative_container_value_type<geometric_container_type>::type & look_up( geometric_container_type & container, const element_type & element )
        {
            return look_up(container, element, typename result_of::associative_container_access_tag<geometric_container_type>::type() );
        }

        template<typename geometric_container_type, typename element_type>
        const typename result_of::associative_container_value_type<geometric_container_type>::type & look_up( const geometric_container_type & container, const element_type & element, random_access_tag )
        {
            return container[ element.id().get() ];
        }

        template<typename geometric_container_type, typename element_type>
        const typename result_of::associative_container_value_type<geometric_container_type>::type & look_up( const geometric_container_type & container, const element_type & element, associative_access_tag )
        {
            typename geometric_container_type::iterator it = container.find( element.id() );
            return it->second;
        }

        template<typename geometric_container_type, typename element_type>
        const typename result_of::associative_container_value_type<geometric_container_type>::type & look_up( const geometric_container_type & container, const element_type & element )
        {
            return look_up(container, element, typename result_of::associative_container_access_tag<geometric_container_type>::type() );
        }

        template<typename geometric_container_type, typename element_type>
        void set( geometric_container_type & container, const element_type & element, const typename result_of::associative_container_value_type<geometric_container_type>::type & info, random_access_tag )
        {
            if (container.size() >= element.id().get() )
                container.resize( element.id().get()+1 );

            container[ element.id().get() ] = info;
        }

        template<typename geometric_container_type, typename element_type>
        void set( geometric_container_type & container, const element_type & element, const typename result_of::associative_container_value_type<geometric_container_type>::type & info, associative_access_tag )
        {
            container.insert(
                std::make_pair( element.id(), info )
            );
        }

        template<typename geometric_container_type, typename element_type>
        void set( geometric_container_type & container, const element_type & element, const typename result_of::associative_container_value_type<geometric_container_type>::type & info )
        {
            set(container, element, info, typename result_of::associative_container_access_tag<geometric_container_type>::type() );
        }
    }
}

namespace viennagrid
{
    namespace result_of
    {
        template<typename container_collection_type, typename element_type, typename metainfo_type>
        struct info_container;

        template<typename container_typemap, typename element_type, typename metainfo_type>
        struct info_container< viennagrid::storage::collection_t<container_typemap>, element_type, metainfo_type >
        {
            typedef typename viennagrid::storage::result_of::container_of< viennagrid::storage::collection_t<container_typemap>, viennameta::static_pair<element_type, metainfo_type> >::type type;
        };
    }

    template< typename element_type, typename metainfo_type, typename container_typemap >
    typename result_of::info_container< viennagrid::storage::collection_t<container_typemap>, element_type, metainfo_type>::type & get_info( viennagrid::storage::collection_t<container_typemap> & container_collection )
    {
        return viennagrid::storage::collection::get< viennameta::static_pair<element_type, metainfo_type> >(container_collection);
    }

    template< typename element_type, typename metainfo_type, typename container_typemap >
    const typename result_of::info_container<viennagrid::storage::collection_t<container_typemap>, element_type, metainfo_type>::type & get_info( const viennagrid::storage::collection_t<container_typemap> & container_collection )
    {
        return viennagrid::storage::collection::get< viennameta::static_pair<element_type, metainfo_type> >(container_collection);
    }

    template<typename metainfo_type, typename metainfo_container_typemap, typename element_type>
    typename metainfo::result_of::associative_container_value_type<
        typename result_of::info_container<
            viennagrid::storage::collection_t<metainfo_container_typemap>,
            element_type,
            metainfo_type
        >::type
    >::type & look_up(
            viennagrid::storage::collection_t<metainfo_container_typemap> & metainfo_collection,
            const element_type & element
        )
    {
        return metainfo::look_up( get_info<element_type, metainfo_type>(metainfo_collection), element );
    }

    template<typename metainfo_type, typename metainfo_container_typemap, typename element_type>
    const typename metainfo::result_of::associative_container_value_type<
        typename result_of::info_container<
            viennagrid::storage::collection_t<metainfo_container_typemap>,
            element_type,
            metainfo_type
        >::type
    >::type & look_up(
            const viennagrid::storage::collection_t<metainfo_container_typemap> & metainfo_collection,
            const element_type & element
        )
    {
        return metainfo::look_up( get_info<element_type, metainfo_type>(metainfo_collection), element );
    }

    template<typename metainfo_type, typename metainfo_container_typemap, typename element_type>
    void set(
            viennagrid::storage::collection_t<metainfo_container_typemap> & metainfo_collection,
             const element_type & element,
             const typename metainfo::result_of::associative_container_value_type<
                typename result_of::info_container<
                    viennagrid::storage::collection_t<metainfo_container_typemap>,
                    element_type,
                    metainfo_type
                >::type
            >::type & meta_info )
    {
        metainfo::set( get_info<element_type, metainfo_type>(metainfo_collection), element, meta_info );
    }

    namespace metainfo
    {

        template<typename element_type, typename cur_typemap>
        struct for_each_element_helper;

        template<typename element_type, typename cur_element_type, typename cur_metainfo_type, typename container_type, typename tail>
        struct for_each_element_helper<
            element_type,
            viennameta::typelist_t<
                viennameta::static_pair<
                    viennameta::static_pair<
                        cur_element_type,
                        cur_metainfo_type
                    >,
                    container_type
                >,
            tail>
        >
        {
            template<typename metainfo_container_typemap, typename functor_type>
            static void exec( storage::collection_t<metainfo_container_typemap> & collection, functor_type functor)
            {
                for_each_element_helper<element_type, tail>::exec(collection, functor);
            }
        };

        template<typename element_type, typename cur_metainfo_type, typename container_type, typename tail>
        struct for_each_element_helper<
            element_type,
            viennameta::typelist_t<
                viennameta::static_pair<
                    viennameta::static_pair<
                        element_type,
                        cur_metainfo_type
                    >,
                    container_type
                >,
            tail>
        >
        {
            template<typename metainfo_container_typemap, typename functor_type>
            static void exec( storage::collection_t<metainfo_container_typemap> & collection, functor_type functor)
            {
                functor( get_info<element_type, cur_metainfo_type>(collection) );
                //get_info<element_type, cur_metainfo_type>(collection).resize( size );
                for_each_element_helper<element_type, tail>::exec(collection, functor);
            }
        };

        template<typename element_type>
        struct for_each_element_helper<
            element_type,
            viennameta::null_type
        >
        {
            template<typename metainfo_container_typemap, typename functor_type>
            static void exec( storage::collection_t<metainfo_container_typemap> & collection, functor_type functor)
            {}
        };

        class resize_functor
        {
        public:
            resize_functor(std::size_t size_) : size(size_) {}

            template<typename container_type>
            void operator() ( container_type & container )
            {
                container.resize(size);
            }

        private:
            std::size_t size;
        };

        template<typename element_type, typename metainfo_container_typemap>
        void resize_container( storage::collection_t<metainfo_container_typemap> & collection, std::size_t size )
        {
            for_each_element_helper<element_type, metainfo_container_typemap>::exec(collection, resize_functor(size) );
        }

        class increment_size_functor
        {
        public:
            increment_size_functor() {}

            template<typename container_type>
            void operator() ( container_type & container )
            {
                container.resize( container.size()+1 );
            }
        };

        template<typename element_type, typename metainfo_container_typemap>
        void increment_size( storage::collection_t<metainfo_container_typemap> & collection )
        {
            for_each_element_helper<element_type, metainfo_container_typemap>::exec(collection, increment_size_functor() );
        }

    }

    namespace result_of
    {
        template<typename pair_type, typename container_config, typename topologic_domain_config>
        struct metainfo_container;

        template<typename element_type, typename metainfo_type, typename container_config, typename topologic_domain_config>
        struct metainfo_container< viennameta::static_pair<element_type, metainfo_type>, container_config, topologic_domain_config >
        {
            typedef typename viennameta::typemap::result_of::find<container_config, viennameta::static_pair<element_type, metainfo_type> >::type search_result;
            typedef typename viennameta::typemap::result_of::find<container_config, viennagrid::storage::default_tag>::type default_container;

            typedef typename viennameta::_if<
                !viennameta::_equal<search_result, viennameta::not_found>::value,
                search_result,
                default_container
            >::type container_tag_pair;

            //typedef typename viennagrid::storage::result_of::container_from_tag<value_type, typename container_tag_pair::second>::type type;
            typedef typename viennagrid::storage::result_of::container<metainfo_type, typename container_tag_pair::second>::type type;
        };

        template<typename element_list, typename container_config, typename topologic_domain_config>
        struct metainfo_container_typemap;

        template<typename container_config, typename topologic_domain_config>
        struct metainfo_container_typemap<viennameta::null_type, container_config, topologic_domain_config>
        {
            typedef viennameta::null_type type;
        };

        template<typename element_tag, typename metainfo_type, typename tail, typename container_config, typename topologic_domain_config>
        struct metainfo_container_typemap<viennameta::typelist_t< viennameta::static_pair<element_tag, metainfo_type>, tail>, container_config, topologic_domain_config>
        {
            typedef typename viennagrid::result_of::element<topologic_domain_config, element_tag>::type element_type;

            typedef viennameta::typelist_t<
                typename viennameta::static_pair<
                        viennameta::static_pair<element_type, metainfo_type>,
                        typename metainfo_container< viennameta::static_pair<element_type, metainfo_type>, container_config, topologic_domain_config>::type
                    >,
                typename metainfo_container_typemap<tail, container_config, topologic_domain_config>::type
            > type;
        };
    }

}

#endif
<commit_msg>fixed const correctness<commit_after>#ifndef VIENNAGRID_METAINFO_HPP
#define VIENNAGRID_METAINFO_HPP

/* =======================================================================
   Copyright (c) 2011-2012, Institute for Microelectronics,
                            Institute for Analysis and Scientific Computing,
                            TU Wien.

                            -----------------
                     ViennaGrid - The Vienna Grid Library
                            -----------------

   Authors:      Karl Rupp                           rupp@iue.tuwien.ac.at
                 Josef Weinbub                    weinbub@iue.tuwien.ac.at

   (A list of additional contributors can be found in the PDF manual)

   License:      MIT (X11), see file LICENSE in the base directory
======================================================================= */

namespace viennagrid
{

    namespace metainfo
    {

        struct random_access_tag {};
        struct associative_access_tag {};

        namespace result_of
        {

            template<typename container_type>
            struct associative_container_value_type
            {
                typedef typename container_type::value_type type;
            };

            template<typename key_type, typename value_type, typename compare, typename allocator>
            struct associative_container_value_type< std::map<key_type, value_type, compare, allocator> >
            {
                typedef value_type type;
            };

            template<typename container_type>
            struct associative_container_access_tag
            {
                typedef random_access_tag type;
            };

            template<typename key_type, typename value_type, typename compare, typename allocator>
            struct associative_container_access_tag< std::map<key_type, value_type, compare, allocator> >
            {
                typedef associative_access_tag type;
            };

        }

        template<typename geometric_container_type, typename element_type>
        typename result_of::associative_container_value_type<geometric_container_type>::type & look_up( geometric_container_type & container, const element_type & element, random_access_tag )
        {
            return container[ element.id().get() ];
        }

        template<typename geometric_container_type, typename element_type>
        typename result_of::associative_container_value_type<geometric_container_type>::type & look_up( geometric_container_type & container, const element_type & element, associative_access_tag )
        {
            typename geometric_container_type::iterator it = container.find( element.id() );
            return it->second;
        }

        template<typename geometric_container_type, typename element_type>
        typename result_of::associative_container_value_type<geometric_container_type>::type & look_up( geometric_container_type & container, const element_type & element )
        {
            return look_up(container, element, typename result_of::associative_container_access_tag<geometric_container_type>::type() );
        }

        template<typename geometric_container_type, typename element_type>
        const typename result_of::associative_container_value_type<geometric_container_type>::type & look_up( const geometric_container_type & container, const element_type & element, random_access_tag )
        {
            return container[ element.id().get() ];
        }

        template<typename geometric_container_type, typename element_type>
        const typename result_of::associative_container_value_type<geometric_container_type>::type & look_up( const geometric_container_type & container, const element_type & element, associative_access_tag )
        {
            typename geometric_container_type::const_iterator it = container.find( element.id() );
            return it->second;
        }

        template<typename geometric_container_type, typename element_type>
        const typename result_of::associative_container_value_type<geometric_container_type>::type & look_up( const geometric_container_type & container, const element_type & element )
        {
            return look_up(container, element, typename result_of::associative_container_access_tag<geometric_container_type>::type() );
        }

        template<typename geometric_container_type, typename element_type>
        void set( geometric_container_type & container, const element_type & element, const typename result_of::associative_container_value_type<geometric_container_type>::type & info, random_access_tag )
        {
            if (container.size() >= element.id().get() )
                container.resize( element.id().get()+1 );

            container[ element.id().get() ] = info;
        }

        template<typename geometric_container_type, typename element_type>
        void set( geometric_container_type & container, const element_type & element, const typename result_of::associative_container_value_type<geometric_container_type>::type & info, associative_access_tag )
        {
            container.insert(
                std::make_pair( element.id(), info )
            );
        }

        template<typename geometric_container_type, typename element_type>
        void set( geometric_container_type & container, const element_type & element, const typename result_of::associative_container_value_type<geometric_container_type>::type & info )
        {
            set(container, element, info, typename result_of::associative_container_access_tag<geometric_container_type>::type() );
        }
    }
}

namespace viennagrid
{
    namespace result_of
    {
        template<typename container_collection_type, typename element_type, typename metainfo_type>
        struct info_container;

        template<typename container_typemap, typename element_type, typename metainfo_type>
        struct info_container< viennagrid::storage::collection_t<container_typemap>, element_type, metainfo_type >
        {
            typedef typename viennagrid::storage::result_of::container_of< viennagrid::storage::collection_t<container_typemap>, viennameta::static_pair<element_type, metainfo_type> >::type type;
        };
    }

    template< typename element_type, typename metainfo_type, typename container_typemap >
    typename result_of::info_container< viennagrid::storage::collection_t<container_typemap>, element_type, metainfo_type>::type & get_info( viennagrid::storage::collection_t<container_typemap> & container_collection )
    {
        return viennagrid::storage::collection::get< viennameta::static_pair<element_type, metainfo_type> >(container_collection);
    }

    template< typename element_type, typename metainfo_type, typename container_typemap >
    const typename result_of::info_container<viennagrid::storage::collection_t<container_typemap>, element_type, metainfo_type>::type & get_info( const viennagrid::storage::collection_t<container_typemap> & container_collection )
    {
        return viennagrid::storage::collection::get< viennameta::static_pair<element_type, metainfo_type> >(container_collection);
    }

    template<typename metainfo_type, typename metainfo_container_typemap, typename element_type>
    typename metainfo::result_of::associative_container_value_type<
        typename result_of::info_container<
            viennagrid::storage::collection_t<metainfo_container_typemap>,
            element_type,
            metainfo_type
        >::type
    >::type & look_up(
            viennagrid::storage::collection_t<metainfo_container_typemap> & metainfo_collection,
            const element_type & element
        )
    {
        return metainfo::look_up( get_info<element_type, metainfo_type>(metainfo_collection), element );
    }

    template<typename metainfo_type, typename metainfo_container_typemap, typename element_type>
    const typename metainfo::result_of::associative_container_value_type<
        typename result_of::info_container<
            viennagrid::storage::collection_t<metainfo_container_typemap>,
            element_type,
            metainfo_type
        >::type
    >::type & look_up(
            const viennagrid::storage::collection_t<metainfo_container_typemap> & metainfo_collection,
            const element_type & element
        )
    {
        return metainfo::look_up( get_info<element_type, metainfo_type>(metainfo_collection), element );
    }

    template<typename metainfo_type, typename metainfo_container_typemap, typename element_type>
    void set(
            viennagrid::storage::collection_t<metainfo_container_typemap> & metainfo_collection,
             const element_type & element,
             const typename metainfo::result_of::associative_container_value_type<
                typename result_of::info_container<
                    viennagrid::storage::collection_t<metainfo_container_typemap>,
                    element_type,
                    metainfo_type
                >::type
            >::type & meta_info )
    {
        metainfo::set( get_info<element_type, metainfo_type>(metainfo_collection), element, meta_info );
    }

    namespace metainfo
    {

        template<typename element_type, typename cur_typemap>
        struct for_each_element_helper;

        template<typename element_type, typename cur_element_type, typename cur_metainfo_type, typename container_type, typename tail>
        struct for_each_element_helper<
            element_type,
            viennameta::typelist_t<
                viennameta::static_pair<
                    viennameta::static_pair<
                        cur_element_type,
                        cur_metainfo_type
                    >,
                    container_type
                >,
            tail>
        >
        {
            template<typename metainfo_container_typemap, typename functor_type>
            static void exec( storage::collection_t<metainfo_container_typemap> & collection, functor_type functor)
            {
                for_each_element_helper<element_type, tail>::exec(collection, functor);
            }
        };

        template<typename element_type, typename cur_metainfo_type, typename container_type, typename tail>
        struct for_each_element_helper<
            element_type,
            viennameta::typelist_t<
                viennameta::static_pair<
                    viennameta::static_pair<
                        element_type,
                        cur_metainfo_type
                    >,
                    container_type
                >,
            tail>
        >
        {
            template<typename metainfo_container_typemap, typename functor_type>
            static void exec( storage::collection_t<metainfo_container_typemap> & collection, functor_type functor)
            {
                functor( get_info<element_type, cur_metainfo_type>(collection) );
                //get_info<element_type, cur_metainfo_type>(collection).resize( size );
                for_each_element_helper<element_type, tail>::exec(collection, functor);
            }
        };

        template<typename element_type>
        struct for_each_element_helper<
            element_type,
            viennameta::null_type
        >
        {
            template<typename metainfo_container_typemap, typename functor_type>
            static void exec( storage::collection_t<metainfo_container_typemap> & collection, functor_type functor)
            {}
        };

        class resize_functor
        {
        public:
            resize_functor(std::size_t size_) : size(size_) {}

            template<typename container_type>
            void operator() ( container_type & container )
            {
                container.resize(size);
            }

        private:
            std::size_t size;
        };

        template<typename element_type, typename metainfo_container_typemap>
        void resize_container( storage::collection_t<metainfo_container_typemap> & collection, std::size_t size )
        {
            for_each_element_helper<element_type, metainfo_container_typemap>::exec(collection, resize_functor(size) );
        }

        class increment_size_functor
        {
        public:
            increment_size_functor() {}

            template<typename container_type>
            void operator() ( container_type & container )
            {
                container.resize( container.size()+1 );
            }
        };

        template<typename element_type, typename metainfo_container_typemap>
        void increment_size( storage::collection_t<metainfo_container_typemap> & collection )
        {
            for_each_element_helper<element_type, metainfo_container_typemap>::exec(collection, increment_size_functor() );
        }

    }

    namespace result_of
    {
        template<typename pair_type, typename container_config, typename topologic_domain_config>
        struct metainfo_container;

        template<typename element_type, typename metainfo_type, typename container_config, typename topologic_domain_config>
        struct metainfo_container< viennameta::static_pair<element_type, metainfo_type>, container_config, topologic_domain_config >
        {
            typedef typename viennameta::typemap::result_of::find<container_config, viennameta::static_pair<element_type, metainfo_type> >::type search_result;
            typedef typename viennameta::typemap::result_of::find<container_config, viennagrid::storage::default_tag>::type default_container;

            typedef typename viennameta::_if<
                !viennameta::_equal<search_result, viennameta::not_found>::value,
                search_result,
                default_container
            >::type container_tag_pair;

            //typedef typename viennagrid::storage::result_of::container_from_tag<value_type, typename container_tag_pair::second>::type type;
            typedef typename viennagrid::storage::result_of::container<metainfo_type, typename container_tag_pair::second>::type type;
        };

        template<typename element_list, typename container_config, typename topologic_domain_config>
        struct metainfo_container_typemap;

        template<typename container_config, typename topologic_domain_config>
        struct metainfo_container_typemap<viennameta::null_type, container_config, topologic_domain_config>
        {
            typedef viennameta::null_type type;
        };

        template<typename element_tag, typename metainfo_type, typename tail, typename container_config, typename topologic_domain_config>
        struct metainfo_container_typemap<viennameta::typelist_t< viennameta::static_pair<element_tag, metainfo_type>, tail>, container_config, topologic_domain_config>
        {
            typedef typename viennagrid::result_of::element<topologic_domain_config, element_tag>::type element_type;

            typedef viennameta::typelist_t<
                typename viennameta::static_pair<
                        viennameta::static_pair<element_type, metainfo_type>,
                        typename metainfo_container< viennameta::static_pair<element_type, metainfo_type>, container_config, topologic_domain_config>::type
                    >,
                typename metainfo_container_typemap<tail, container_config, topologic_domain_config>::type
            > type;
        };
    }

}

#endif
<|endoftext|>


<commit_before>/*
Implement parallel vectorize workqueue on top of Intel TBB.
*/

#define TBB_PREVIEW_WAITING_FOR_WORKERS 1
/* tbb.h redefines these */
#include "../../_pymodule.h"
#ifdef _POSIX_C_SOURCE
#undef _POSIX_C_SOURCE
#endif
#ifdef _XOPEN_SOURCE
#undef _XOPEN_SOURCE
#endif

#include <tbb/tbb.h>
#include <string.h>
#include <stdio.h>
#include <thread>
#include "workqueue.h"

#include "gufunc_scheduler.h"

/* TBB 2019 U5 is the minimum required version as this is needed:
 * https://github.com/intel/tbb/blob/18070344d755ece04d169e6cc40775cae9288cee/CHANGES#L133-L134
 * and therefore
 * https://github.com/intel/tbb/blob/18070344d755ece04d169e6cc40775cae9288cee/CHANGES#L128-L129
 * from here:
 * https://github.com/intel/tbb/blob/2019_U5/include/tbb/tbb_stddef.h#L29
 */
#if TBB_INTERFACE_VERSION < 12010
#error "TBB version is too old, 2021 update 1, i.e. TBB_INTERFACE_VERSION >= 12010 required"
#endif

#define _DEBUG 0
#define _TRACE_SPLIT 0

static tbb::task_group *tg = NULL;

static tbb::task_scheduler_handle tsh;
static bool tsh_was_initialized = false;

#ifdef _MSC_VER
#define THREAD_LOCAL(ty) __declspec(thread) ty
#else
/* Non-standard C99 extension that's understood by gcc and clang */
#define THREAD_LOCAL(ty) __thread ty
#endif

// This is the number of threads that is default, it is set on initialisation of
// the threading backend via the launch_threads() call
static int _INIT_NUM_THREADS = -1;

// This is the per-thread thread mask, each thread can carry its own mask.
static THREAD_LOCAL(int) _TLS_num_threads = 0;

static void
set_num_threads(int count)
{
    _TLS_num_threads = count;
}

static int
get_num_threads(void)
{
    if (_TLS_num_threads == 0)
    {
        // This is a thread that did not call launch_threads() but is still a
        // "main" thread, probably from e.g. threading.Thread() use, it still
        // has a TLS slot which is 0 from the lack of launch_threads() call
        _TLS_num_threads = _INIT_NUM_THREADS;
    }
    return _TLS_num_threads;
}

static int
get_thread_id(void)
{
    return tbb::this_task_arena::current_thread_index();
}

// watch the arena, if it decides to create more threads/add threads into the
// arena then make sure they get the right thread count
class fix_tls_observer: public tbb::task_scheduler_observer {
    int mask_val;
    void on_scheduler_entry( bool is_worker ) override;
public:
    fix_tls_observer(tbb::task_arena &arena, int mask) : tbb::task_scheduler_observer(arena), mask_val(mask)
    {
        observe(true);
    }
};

void fix_tls_observer::on_scheduler_entry(bool worker) {
    set_num_threads(mask_val);
}

static void
add_task(void *fn, void *args, void *dims, void *steps, void *data)
{
    tg->run([=]
    {
        auto func = reinterpret_cast<void (*)(void *args, void *dims, void *steps, void *data)>(fn);
        func(args, dims, steps, data);
    });
}

static void
parallel_for(void *fn, char **args, size_t *dimensions, size_t *steps, void *data,
             size_t inner_ndim, size_t array_count, int num_threads)
{
    static bool printed = false;
    if(!printed && _DEBUG)
    {
        puts("Using parallel_for");
        printed = true;
    }

    //     args = <ir.Argument '.1' of type i8**>,
    //     dimensions = <ir.Argument '.2' of type i64*>
    //     steps = <ir.Argument '.3' of type i64*>
    //     data = <ir.Argument '.4' of type i8*>

    const size_t arg_len = (inner_ndim + 1);

    if(_DEBUG && _TRACE_SPLIT)
    {
        printf("inner_ndim: %lu\n",inner_ndim);
        printf("arg_len: %lu\n", arg_len);
        printf("total: %lu\n", dimensions[0]);
        printf("dimensions: ");
        for(size_t j = 0; j < arg_len; j++)
            printf("%lu, ", ((size_t *)dimensions)[j]);
        printf("\nsteps: ");
        for(size_t j = 0; j < array_count; j++)
            printf("%lu, ", steps[j]);
        printf("\n*args: ");
        for(size_t j = 0; j < array_count; j++)
            printf("%p, ", (void *)args[j]);
        printf("\n");
    }

    // This is making the assumption that the calling thread knows the truth
    // about num_threads, which should be correct via the following:
    // program starts/reinits and the threadpool launches, num_threads TLS is
    // set as default. Any thread spawned on init making a call to this function
    // will have a valid num_threads TLS slot and so the task_arena is sized
    // appropriately and it's value is used in the observer that fixes the TLS
    // slots of any subsequent threads joining the task_arena. This leads to
    // all threads in a task_arena having valid num_threads TLS slots prior to
    // doing any work. Any further call to query the TLS slot value made by any
    // thread in the arena is then safe and were any thread to create a nested
    // parallel region the same logic applies as per program start/reinit.
    tbb::task_arena limited(num_threads);
    fix_tls_observer observer(limited, num_threads);

    limited.execute([&]{
        using range_t = tbb::blocked_range<size_t>;
        tbb::parallel_for(range_t(0, dimensions[0]), [=](const range_t &range)
        {
            size_t * count_space = (size_t *)alloca(sizeof(size_t) * arg_len);
            char ** array_arg_space = (char**)alloca(sizeof(char*) * array_count);
            memcpy(count_space, dimensions, arg_len * sizeof(size_t));
            count_space[0] = range.size();

            if(_DEBUG && _TRACE_SPLIT > 1)
            {
                printf("THREAD %p:", count_space);
                printf("count_space: ");
                for(size_t j = 0; j < arg_len; j++)
                    printf("%lu, ", count_space[j]);
                printf("\n");
            }
            for(size_t j = 0; j < array_count; j++)
            {
                char * base = args[j];
                size_t step = steps[j];
                ptrdiff_t offset = step * range.begin();
                array_arg_space[j] = base + offset;

                if(_DEBUG && _TRACE_SPLIT > 2)
                {
                    printf("Index %ld\n", j);
                    printf("-->Got base %p\n", (void *)base);
                    printf("-->Got step %lu\n", step);
                    printf("-->Got offset %ld\n", offset);
                    printf("-->Got addr %p\n", (void *)array_arg_space[j]);
                }
            }

            if(_DEBUG && _TRACE_SPLIT > 2)
            {
                printf("array_arg_space: ");
                for(size_t j = 0; j < array_count; j++)
                    printf("%p, ", (void *)array_arg_space[j]);
                printf("\n");
            }
            auto func = reinterpret_cast<void (*)(char **args, size_t *dims, size_t *steps, void *data)>(fn);
            func(array_arg_space, count_space, steps, data);
        });
    });
}

static std::thread::id init_thread_id;
static THREAD_LOCAL(bool) need_reinit_after_fork = false;

static void set_main_thread()
{
    init_thread_id = std::this_thread::get_id();
}

static bool is_main_thread()
{
    return std::this_thread::get_id() == init_thread_id;
}

static void prepare_fork(void)
{
    if(_DEBUG)
    {
        puts("Suspending TBB: prepare fork");
    }
    if (tsh_was_initialized)
    {
        if(is_main_thread())
        {
            if (tbb::finalize(tsh, std::nothrow))
            {
                tsh_was_initialized = false;
                need_reinit_after_fork = true;
            }
            else
            {
                puts("Unable to join threads to shut down before fork(). "
                     "This can break multithreading in child processes.\n");
            }
        }
        else
        {
            fprintf(stderr, "Numba: Attempted to fork from a non-main thread, "
                            "the TBB library may be in an invalid state in the "
                            "child process.\n");
        }
    }
}

static void reset_after_fork(void)
{
    if(_DEBUG)
    {
        puts("Resuming TBB: after fork");
    }

    if(need_reinit_after_fork)
    {
        tsh = tbb::task_scheduler_handle::get();
        set_main_thread();
        need_reinit_after_fork = false;
    }
}

static void unload_tbb(void)
{
    if (tg)
    {
        if(_DEBUG)
        {
            puts("Unloading TBB");
        }
        tg->wait();
        delete tg;
        tg = NULL;
    }
    if (tsh_was_initialized)
    {
        // blocking terminate is not strictly required here, ignore return value
        (void)tbb::finalize(tsh, std::nothrow);
        tsh_was_initialized = false;
    }
}

static void launch_threads(int count)
{
    if(tg)
        return;

    if(_DEBUG)
        puts("Using TBB");

    if(count < 1)
        count = tbb::task_arena::automatic;

    tsh = tbb::task_scheduler_handle::get();
    tsh_was_initialized = true;

    tg = new tbb::task_group;
    tg->run([] {}); // start creating threads asynchronously

    _INIT_NUM_THREADS = count;

    set_main_thread();

#ifndef _MSC_VER
    pthread_atfork(prepare_fork, reset_after_fork, reset_after_fork);
#endif
}

static void synchronize(void)
{
    tg->wait();
}

static void ready(void)
{
}

MOD_INIT(tbbpool)
{
    PyObject *m;
    MOD_DEF(m, "tbbpool", "No docs", NULL)
    if (m == NULL)
        return MOD_ERROR_VAL;
    PyModuleDef *md = PyModule_GetDef(m);
    if (md)
    {
        md->m_free = (freefunc)unload_tbb;
    }
    PyObject_SetAttrString(m, "launch_threads",
                           PyLong_FromVoidPtr((void*)&launch_threads));
    PyObject_SetAttrString(m, "synchronize",
                           PyLong_FromVoidPtr((void*)&synchronize));
    PyObject_SetAttrString(m, "ready",
                           PyLong_FromVoidPtr((void*)&ready));
    PyObject_SetAttrString(m, "add_task",
                           PyLong_FromVoidPtr((void*)&add_task));
    PyObject_SetAttrString(m, "parallel_for",
                           PyLong_FromVoidPtr((void*)&parallel_for));
    PyObject_SetAttrString(m, "do_scheduling_signed",
                           PyLong_FromVoidPtr((void*)&do_scheduling_signed));
    PyObject_SetAttrString(m, "do_scheduling_unsigned",
                           PyLong_FromVoidPtr((void*)&do_scheduling_unsigned));
    PyObject_SetAttrString(m, "set_num_threads",
                           PyLong_FromVoidPtr((void*)&set_num_threads));
    PyObject_SetAttrString(m, "get_num_threads",
                           PyLong_FromVoidPtr((void*)&get_num_threads));
    PyObject_SetAttrString(m, "get_thread_id",
                           PyLong_FromVoidPtr((void*)&get_thread_id));

    return MOD_SUCCESS_VAL(m);
}
<commit_msg>Fix lifetime of task_scheduler_handle<commit_after>/*
Implement parallel vectorize workqueue on top of Intel TBB.
*/

#define TBB_PREVIEW_WAITING_FOR_WORKERS 1
/* tbb.h redefines these */
#include "../../_pymodule.h"
#ifdef _POSIX_C_SOURCE
#undef _POSIX_C_SOURCE
#endif
#ifdef _XOPEN_SOURCE
#undef _XOPEN_SOURCE
#endif

#include <tbb/tbb.h>
#include <string.h>
#include <stdio.h>
#include <thread>
#include "workqueue.h"

#include "gufunc_scheduler.h"

/* TBB 2019 U5 is the minimum required version as this is needed:
 * https://github.com/intel/tbb/blob/18070344d755ece04d169e6cc40775cae9288cee/CHANGES#L133-L134
 * and therefore
 * https://github.com/intel/tbb/blob/18070344d755ece04d169e6cc40775cae9288cee/CHANGES#L128-L129
 * from here:
 * https://github.com/intel/tbb/blob/2019_U5/include/tbb/tbb_stddef.h#L29
 */
#if TBB_INTERFACE_VERSION < 12010
#error "TBB version is too old, 2021 update 1, i.e. TBB_INTERFACE_VERSION >= 12010 required"
#endif

#define _DEBUG 0
#define _TRACE_SPLIT 0

static tbb::task_group *tg = NULL;

static tbb::task_scheduler_handle tsh;
static bool tsh_was_initialized = false;

#ifdef _MSC_VER
#define THREAD_LOCAL(ty) __declspec(thread) ty
#else
/* Non-standard C99 extension that's understood by gcc and clang */
#define THREAD_LOCAL(ty) __thread ty
#endif

// This is the number of threads that is default, it is set on initialisation of
// the threading backend via the launch_threads() call
static int _INIT_NUM_THREADS = -1;

// This is the per-thread thread mask, each thread can carry its own mask.
static THREAD_LOCAL(int) _TLS_num_threads = 0;

static void
set_num_threads(int count)
{
    _TLS_num_threads = count;
}

static int
get_num_threads(void)
{
    if (_TLS_num_threads == 0)
    {
        // This is a thread that did not call launch_threads() but is still a
        // "main" thread, probably from e.g. threading.Thread() use, it still
        // has a TLS slot which is 0 from the lack of launch_threads() call
        _TLS_num_threads = _INIT_NUM_THREADS;
    }
    return _TLS_num_threads;
}

static int
get_thread_id(void)
{
    return tbb::this_task_arena::current_thread_index();
}

// watch the arena, if it decides to create more threads/add threads into the
// arena then make sure they get the right thread count
class fix_tls_observer: public tbb::task_scheduler_observer {
    int mask_val;
    void on_scheduler_entry( bool is_worker ) override;
public:
    fix_tls_observer(tbb::task_arena &arena, int mask) : tbb::task_scheduler_observer(arena), mask_val(mask)
    {
        observe(true);
    }
};

void fix_tls_observer::on_scheduler_entry(bool worker) {
    set_num_threads(mask_val);
}

static void
add_task(void *fn, void *args, void *dims, void *steps, void *data)
{
    tg->run([=]
    {
        auto func = reinterpret_cast<void (*)(void *args, void *dims, void *steps, void *data)>(fn);
        func(args, dims, steps, data);
    });
}

static void
parallel_for(void *fn, char **args, size_t *dimensions, size_t *steps, void *data,
             size_t inner_ndim, size_t array_count, int num_threads)
{
    static bool printed = false;
    if(!printed && _DEBUG)
    {
        puts("Using parallel_for");
        printed = true;
    }

    //     args = <ir.Argument '.1' of type i8**>,
    //     dimensions = <ir.Argument '.2' of type i64*>
    //     steps = <ir.Argument '.3' of type i64*>
    //     data = <ir.Argument '.4' of type i8*>

    const size_t arg_len = (inner_ndim + 1);

    if(_DEBUG && _TRACE_SPLIT)
    {
        printf("inner_ndim: %lu\n",inner_ndim);
        printf("arg_len: %lu\n", arg_len);
        printf("total: %lu\n", dimensions[0]);
        printf("dimensions: ");
        for(size_t j = 0; j < arg_len; j++)
            printf("%lu, ", ((size_t *)dimensions)[j]);
        printf("\nsteps: ");
        for(size_t j = 0; j < array_count; j++)
            printf("%lu, ", steps[j]);
        printf("\n*args: ");
        for(size_t j = 0; j < array_count; j++)
            printf("%p, ", (void *)args[j]);
        printf("\n");
    }

    // This is making the assumption that the calling thread knows the truth
    // about num_threads, which should be correct via the following:
    // program starts/reinits and the threadpool launches, num_threads TLS is
    // set as default. Any thread spawned on init making a call to this function
    // will have a valid num_threads TLS slot and so the task_arena is sized
    // appropriately and it's value is used in the observer that fixes the TLS
    // slots of any subsequent threads joining the task_arena. This leads to
    // all threads in a task_arena having valid num_threads TLS slots prior to
    // doing any work. Any further call to query the TLS slot value made by any
    // thread in the arena is then safe and were any thread to create a nested
    // parallel region the same logic applies as per program start/reinit.
    tbb::task_arena limited(num_threads);
    fix_tls_observer observer(limited, num_threads);

    limited.execute([&]{
        using range_t = tbb::blocked_range<size_t>;
        tbb::parallel_for(range_t(0, dimensions[0]), [=](const range_t &range)
        {
            size_t * count_space = (size_t *)alloca(sizeof(size_t) * arg_len);
            char ** array_arg_space = (char**)alloca(sizeof(char*) * array_count);
            memcpy(count_space, dimensions, arg_len * sizeof(size_t));
            count_space[0] = range.size();

            if(_DEBUG && _TRACE_SPLIT > 1)
            {
                printf("THREAD %p:", count_space);
                printf("count_space: ");
                for(size_t j = 0; j < arg_len; j++)
                    printf("%lu, ", count_space[j]);
                printf("\n");
            }
            for(size_t j = 0; j < array_count; j++)
            {
                char * base = args[j];
                size_t step = steps[j];
                ptrdiff_t offset = step * range.begin();
                array_arg_space[j] = base + offset;

                if(_DEBUG && _TRACE_SPLIT > 2)
                {
                    printf("Index %ld\n", j);
                    printf("-->Got base %p\n", (void *)base);
                    printf("-->Got step %lu\n", step);
                    printf("-->Got offset %ld\n", offset);
                    printf("-->Got addr %p\n", (void *)array_arg_space[j]);
                }
            }

            if(_DEBUG && _TRACE_SPLIT > 2)
            {
                printf("array_arg_space: ");
                for(size_t j = 0; j < array_count; j++)
                    printf("%p, ", (void *)array_arg_space[j]);
                printf("\n");
            }
            auto func = reinterpret_cast<void (*)(char **args, size_t *dims, size_t *steps, void *data)>(fn);
            func(array_arg_space, count_space, steps, data);
        });
    });
}

static std::thread::id init_thread_id;
static THREAD_LOCAL(bool) need_reinit_after_fork = false;

static void set_main_thread()
{
    init_thread_id = std::this_thread::get_id();
}

static bool is_main_thread()
{
    return std::this_thread::get_id() == init_thread_id;
}

static void prepare_fork(void)
{
    if(_DEBUG)
    {
        puts("Suspending TBB: prepare fork");
    }
    if (tsh_was_initialized)
    {
        if(is_main_thread())
        {
            if (!tbb::finalize(tsh, std::nothrow))
            {
                tbb::task_scheduler_handle::release(tsh);
                puts("Unable to join threads to shut down before fork(). "
                     "This can break multithreading in child processes.\n");
            }
            tsh_was_initialized = false;
            need_reinit_after_fork = true;
        }
        else
        {
            fprintf(stderr, "Numba: Attempted to fork from a non-main thread, "
                            "the TBB library may be in an invalid state in the "
                            "child process.\n");
        }
    }
}

static void reset_after_fork(void)
{
    if(_DEBUG)
    {
        puts("Resuming TBB: after fork");
    }

    if(need_reinit_after_fork)
    {
        tsh = tbb::task_scheduler_handle::get();
        set_main_thread();
        tsh_was_initialized = true;
        need_reinit_after_fork = false;
    }
}

static void unload_tbb(void)
{
    if (tg)
    {
        if(_DEBUG)
        {
            puts("Unloading TBB");
        }
        tg->wait();
        delete tg;
        tg = NULL;
    }
    if (tsh_was_initialized)
    {
        // blocking terminate is not strictly required here, ignore return value
        (void)tbb::finalize(tsh, std::nothrow);
        tsh_was_initialized = false;
    }
}

static void launch_threads(int count)
{
    if(tg)
        return;

    if(_DEBUG)
        puts("Using TBB");

    if(count < 1)
        count = tbb::task_arena::automatic;

    tsh = tbb::task_scheduler_handle::get();
    tsh_was_initialized = true;

    tg = new tbb::task_group;
    tg->run([] {}); // start creating threads asynchronously

    _INIT_NUM_THREADS = count;

    set_main_thread();

#ifndef _MSC_VER
    pthread_atfork(prepare_fork, reset_after_fork, reset_after_fork);
#endif
}

static void synchronize(void)
{
    tg->wait();
}

static void ready(void)
{
}

MOD_INIT(tbbpool)
{
    PyObject *m;
    MOD_DEF(m, "tbbpool", "No docs", NULL)
    if (m == NULL)
        return MOD_ERROR_VAL;
    PyModuleDef *md = PyModule_GetDef(m);
    if (md)
    {
        md->m_free = (freefunc)unload_tbb;
    }
    PyObject_SetAttrString(m, "launch_threads",
                           PyLong_FromVoidPtr((void*)&launch_threads));
    PyObject_SetAttrString(m, "synchronize",
                           PyLong_FromVoidPtr((void*)&synchronize));
    PyObject_SetAttrString(m, "ready",
                           PyLong_FromVoidPtr((void*)&ready));
    PyObject_SetAttrString(m, "add_task",
                           PyLong_FromVoidPtr((void*)&add_task));
    PyObject_SetAttrString(m, "parallel_for",
                           PyLong_FromVoidPtr((void*)&parallel_for));
    PyObject_SetAttrString(m, "do_scheduling_signed",
                           PyLong_FromVoidPtr((void*)&do_scheduling_signed));
    PyObject_SetAttrString(m, "do_scheduling_unsigned",
                           PyLong_FromVoidPtr((void*)&do_scheduling_unsigned));
    PyObject_SetAttrString(m, "set_num_threads",
                           PyLong_FromVoidPtr((void*)&set_num_threads));
    PyObject_SetAttrString(m, "get_num_threads",
                           PyLong_FromVoidPtr((void*)&get_num_threads));
    PyObject_SetAttrString(m, "get_thread_id",
                           PyLong_FromVoidPtr((void*)&get_thread_id));

    return MOD_SUCCESS_VAL(m);
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: staticassert.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: kz $ $Date: 2003-12-09 11:47:53 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
#ifndef WW_STATICASSERT_HXX
#define WW_STATICASSERT_HXX

/*
 Lifted direct from:
 Modern C++ Design: Generic Programming and Design Patterns Applied
 Section 2.1
 by Andrei Alexandrescu
*/
namespace ww
{
    template<bool> class compile_time_check
    {
    public:
        compile_time_check(...) {}
    };

    template<> class compile_time_check<false>
    {
    };
}

    /*
    Similiar to assert, StaticAssert is only in operation when NDEBUG is not
    defined. It will test its first argument at compile time and on failure
    report the error message of the second argument, which must be a valid c++
    classname. i.e. no spaces, punctuation or reserved keywords.
    */
#ifndef NDEBUG
#   define StaticAssert(test, errormsg)                         \
    do {                                                        \
        struct ERROR_##errormsg {};                             \
        typedef ww::compile_time_check< (test) != 0 > tmplimpl; \
        tmplimpl aTemp = tmplimpl(ERROR_##errormsg());          \
        sizeof(aTemp);                                          \
    } while (0)
#else
#   define StaticAssert(test, errormsg)                         \
    do {} while (0)
#endif

#endif
/* vi:set tabstop=4 shiftwidth=4 expandtab: */
<commit_msg>INTEGRATION: CWS ooo19126 (1.4.896); FILE MERGED 2005/09/05 13:42:29 rt 1.4.896.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: staticassert.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 06:05:02 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
#ifndef WW_STATICASSERT_HXX
#define WW_STATICASSERT_HXX

/*
 Lifted direct from:
 Modern C++ Design: Generic Programming and Design Patterns Applied
 Section 2.1
 by Andrei Alexandrescu
*/
namespace ww
{
    template<bool> class compile_time_check
    {
    public:
        compile_time_check(...) {}
    };

    template<> class compile_time_check<false>
    {
    };
}

    /*
    Similiar to assert, StaticAssert is only in operation when NDEBUG is not
    defined. It will test its first argument at compile time and on failure
    report the error message of the second argument, which must be a valid c++
    classname. i.e. no spaces, punctuation or reserved keywords.
    */
#ifndef NDEBUG
#   define StaticAssert(test, errormsg)                         \
    do {                                                        \
        struct ERROR_##errormsg {};                             \
        typedef ww::compile_time_check< (test) != 0 > tmplimpl; \
        tmplimpl aTemp = tmplimpl(ERROR_##errormsg());          \
        sizeof(aTemp);                                          \
    } while (0)
#else
#   define StaticAssert(test, errormsg)                         \
    do {} while (0)
#endif

#endif
/* vi:set tabstop=4 shiftwidth=4 expandtab: */
<|endoftext|>


<commit_before>#ifndef VIENNAGRID_ALGORITHM_ANGLE_HPP
#define VIENNAGRID_ALGORITHM_ANGLE_HPP

/* =======================================================================
   Copyright (c) 2011-2013, Institute for Microelectronics,
                            Institute for Analysis and Scientific Computing,
                            TU Wien.

                            -----------------
                     ViennaGrid - The Vienna Grid Library
                            -----------------

   License:      MIT (X11), see file LICENSE in the base directory
======================================================================= */

namespace viennagrid
{
  namespace detail
  {
    template<typename DomainType, typename ScalarType, typename PointAccessorType>
    void scale_impl(DomainType& domain, ScalarType factor, PointAccessorType accessor)
    {
      typedef typename viennagrid::result_of::element<DomainType, viennagrid::vertex_tag>::type         VertexType;
      typedef typename viennagrid::result_of::element_range<DomainType, viennagrid::vertex_tag>::type   VertexContainer;
      typedef typename viennagrid::result_of::iterator<VertexContainer>::type                           VertexIterator;

      VertexContainer vertices = viennagrid::elements<VertexType>(domain);
      for ( VertexIterator vit = vertices.begin();
            vit != vertices.end();
            ++vit )
      {
          accessor(*vit) *= factor;
      }
    }
  } // detail

  template<typename DomainType, typename ScalarType>
  void scale(DomainType& domain, ScalarType factor)
  {
    viennagrid::detail::scale_impl(domain, factor, viennagrid::default_point_accessor(domain));
  }

} // viennagrid

#endif
<commit_msg>Fixed include guard<commit_after>#ifndef VIENNAGRID_ALGORITHM_SCALE_HPP
#define VIENNAGRID_ALGORITHM_SCALE_HPP

/* =======================================================================
   Copyright (c) 2011-2013, Institute for Microelectronics,
                            Institute for Analysis and Scientific Computing,
                            TU Wien.

                            -----------------
                     ViennaGrid - The Vienna Grid Library
                            -----------------

   License:      MIT (X11), see file LICENSE in the base directory
======================================================================= */

namespace viennagrid
{
  namespace detail
  {
    template<typename DomainType, typename ScalarType, typename PointAccessorType>
    void scale_impl(DomainType& domain, ScalarType factor, PointAccessorType accessor)
    {
      typedef typename viennagrid::result_of::element<DomainType, viennagrid::vertex_tag>::type         VertexType;
      typedef typename viennagrid::result_of::element_range<DomainType, viennagrid::vertex_tag>::type   VertexContainer;
      typedef typename viennagrid::result_of::iterator<VertexContainer>::type                           VertexIterator;

      VertexContainer vertices = viennagrid::elements<VertexType>(domain);
      for ( VertexIterator vit = vertices.begin();
            vit != vertices.end();
            ++vit )
      {
          accessor(*vit) *= factor;
      }
    }
  } // detail

  template<typename DomainType, typename ScalarType>
  void scale(DomainType& domain, ScalarType factor)
  {
    viennagrid::detail::scale_impl(domain, factor, viennagrid::default_point_accessor(domain));
  }

} // viennagrid

#endif
<|endoftext|>