text:
#include "precompiled.h"
#include "typescript.d.bootstrap.h"

#include "mangle.h"
#include "walk_symbol.h"
#include "jstypes.h"

using tc::jst::create_js_object;
using tc::js::string;
using tc::jst::optional;
using tc::js::any;
using tc::js::ts;
using tc::js::Array;
using tc::js::ReadonlyArray;

std::optional<ts::TypeChecker> g_ojtsTypeChecker;
bool g_bGlobalScopeConstructionComplete = true;

namespace {
	std::string RetrieveSymbolFromCpp(ts::Symbol jsymSymbol) noexcept {
		auto const str = FullyQualifiedName(jsymSymbol);
		std::string strResult;

		auto strSplit = tc::as_pointers(str);
		while(!tc::empty(strSplit)) {
			auto const strLocal = [&]() noexcept {
				if(tc::starts_with<tc::return_bool>(strSplit, "\"")) {
					tc::drop_first_inplace(strSplit);

					auto itch = tc::find_first<tc::return_element>(strSplit, '\"');
					auto str = tc::take(strSplit, itch);

					tc::drop_inplace(strSplit, itch + 1);
					if(!tc::empty(strSplit)) {
						_ASSERT('.' == tc::front(strSplit));
						tc::drop_first_inplace(strSplit);
					}

					return str;
				} else if(auto itch = tc::find_first<tc::return_element_or_null>(strSplit, '.')) {
					auto str = tc::take(strSplit, itch);
					tc::drop_inplace(strSplit, itch + 1);
					return str;
				} else {
					auto str = strSplit;
					tc::drop_inplace(strSplit, tc::end(strSplit));
					return str;
				}
			}();

			if(tc::empty(strResult)) {
				tc::append(strResult, "emscripten::val::global(\"", strLocal, "\")");
			} else {
				tc::append(strResult, "[\"", strLocal, "\"]");
			}
		}
		return strResult;
	}

	template<typename SetJsXXX, typename Func>
	std::vector<typename SetJsXXX::value_type const*> SortDeclarationOrder(SetJsXXX& setjs, Func ForEachChild) noexcept {
		std::unordered_set<std::string> setstrSeen;
		std::vector<typename SetJsXXX::value_type const*> vecpjs;

		auto dfs = [&](auto const& js, auto const& dfs) {
			if(!setstrSeen.insert(js.m_strQualifiedName).second) {
				return;
			}
			ForEachChild(js, [&](auto const& jsChild) {
				dfs(jsChild, dfs);
			});
			tc::cont_emplace_back(vecpjs, std::addressof(js));
		};

		tc::for_each(setjs, [&](auto const& js) noexcept {
			dfs(js, dfs);
		});
		return vecpjs;
	}
}

SetJsEnum g_setjsenum;
SetJsClass g_setjsclass;
SetJsTypeAlias g_setjstypealias;

std::unordered_set<std::string> g_setstrIgnoredSymbols;
bool IsIgnoredSymbol(std::string const& strFullyQualified) noexcept {
	return tc::cont_find<tc::return_bool>(
		g_setstrIgnoredSymbols,
		strFullyQualified
	);
}

template<typename Rng>
void CompileProgram(ts::Program jtsProgram, Rng const& rngstrFileNames) noexcept {
	*g_ojtsTypeChecker = jtsProgram->getTypeChecker();

	// Iterate over source files, enumerate global symbols and then walk the tree of child symbols
	SJsScope scopeGlobal(
		[&]() noexcept {
			std::vector<ts::Symbol> vecjsymExportedSymbol;
			tc::for_each(
				tc::filter(
					jtsProgram->getSourceFiles(),
					[&](ts::SourceFile jtsSourceFile) noexcept {
						// Only generate output for our input source files, not for their dependencies
						return tc::find_unique<tc::return_bool>(rngstrFileNames, tc::explicit_cast<std::string>(jtsSourceFile->fileName()));
					}
				),
				[&](ts::SourceFile jtsSourceFile) noexcept {
					if(auto const josymSourceFile = (*g_ojtsTypeChecker)->getSymbolAtLocation(jtsSourceFile)) {
						tc::cont_emplace_back(vecjsymExportedSymbol, *josymSourceFile);
					} else {
						tc::append(std::cerr, "Module not found for ", tc::explicit_cast<std::string>(jtsSourceFile->fileName()), ", treating at as a global library\n");
						ts::forEachChild(jtsSourceFile, tc::jst::lambda([&](ts::Node jnodeChild) noexcept -> tc::jst::union_t<double, tc::js::undefined> {
							if (auto const jotsFunctionDeclaration = ts::isFunctionDeclaration(jnodeChild)) {
								tc::cont_emplace_back(vecjsymExportedSymbol, *(*g_ojtsTypeChecker)->getSymbolAtLocation(*(*jotsFunctionDeclaration)->name()));
							} else if (auto const jotsVariableStatement = ts::isVariableStatement(jnodeChild)) {
								tc::for_each((*jotsVariableStatement)->declarationList()->declarations(), [&](ts::VariableDeclaration jtsVariableDeclaration) noexcept {
									tc::cont_emplace_back(vecjsymExportedSymbol, *(*g_ojtsTypeChecker)->getSymbolAtLocation(jtsVariableDeclaration->name()));
								});
							} else if (auto const jotsClassDeclaration = ts::isClassDeclaration(jnodeChild)) {
								tc::cont_emplace_back(vecjsymExportedSymbol, *(*g_ojtsTypeChecker)->getSymbolAtLocation(*(*jotsClassDeclaration)->name()));
							} else if (auto const jotsInterfaceDeclaration = ts::isInterfaceDeclaration(jnodeChild)) {
								tc::cont_emplace_back(vecjsymExportedSymbol, *(*g_ojtsTypeChecker)->getSymbolAtLocation((*jotsInterfaceDeclaration)->name()));
							} else if (auto const jotsEnumDeclaration = ts::isEnumDeclaration(jnodeChild)) {
								tc::cont_emplace_back(vecjsymExportedSymbol, *(*g_ojtsTypeChecker)->getSymbolAtLocation((*jotsEnumDeclaration)->name()));
							} else if (auto const jotsModuleDeclaration = ts::isModuleDeclaration(jnodeChild)) {
								tc::cont_emplace_back(vecjsymExportedSymbol, *(*g_ojtsTypeChecker)->getSymbolAtLocation((*jotsModuleDeclaration)->name()));
							} else if(auto const jotsTypeAliasDeclaration = ts::isTypeAliasDeclaration(jnodeChild)) {
								tc::cont_emplace_back(vecjsymExportedSymbol, *(*g_ojtsTypeChecker)->getSymbolAtLocation((*jotsTypeAliasDeclaration)->name()));
							} else if (ts::SyntaxKind::EndOfFileToken == jnodeChild->kind()) {
								// Do nothing
							} else {
								tc::append(std::cerr, "Unknown source file-level child kind: ", tc::as_dec(static_cast<int>(jnodeChild->kind())), "\n");
							}
							return tc::js::undefined();
						}));
					}
				}
			);

			// Make list of exported symbols unique

			// An interface declaration and a variable statement may introduce the same symbol, e.g.,
			// interface EventTarget {
			// }

			// var EventTarget: {
			// 	prototype: EventTarget;
			// 	new(): EventTarget;
			// };
			//
			// These define the same C++ class

			// Overloaded functions also define the same symbol with two declarations:

			// function test(a: number);
			// function test(a: string);

			// For more combinations see tests/duplicate_symbols and https://www.typescriptlang.org/docs/handbook/declaration-files/deep-dive.html#advanced-combinations
			tc::sort_unique_inplace(vecjsymExportedSymbol, tc::projected(tc::fn_less(), [](ts::Symbol jsym) noexcept {
				return FullyQualifiedName(jsym);
			}));

			return vecjsymExportedSymbol;
		}()
	);

	tc::for_each(g_setjsclass, TC_MEMBER(.ResolveBaseClassesAndSortDependencies()));

	// Can call MangleType once construction of the global scope is complete
	g_bGlobalScopeConstructionComplete = true;

	{

		tc::for_each(g_setjsclass, [&](SJsClass& jsclass) noexcept {
			MergeWithSameCppSignatureInplace(jsclass.m_vecjsfunctionlikeMethod);
			MergeWithSameCppSignatureInplace(jsclass.m_vecjsfunctionlikeExport);
		});
		MergeWithSameCppSignatureInplace(scopeGlobal.m_vecjsfunctionlikeExport);

		// Find correct declaration order by going depth-first over class hierarchy
		// Typescript has no requirements on declaration order of type aliases. This is valid typescript:
		// type FooBar2 = FooBar;
		// type FooBar = number | string;
		// In C++, FooBar must be declared before FooBar2.
		// For each type alias declaration, we iterate depth-first over all type aliases referenced on the right-hand side
		// and emit them first.

		// Sort the sequenced indices of g_setjsclass/g_setjstypealias
		std::vector<SJsClass const*> vecpjsclassSorted = SortDeclarationOrder(
			g_setjsclass,
			[](SJsClass const& jsclass, auto ForEachChild) noexcept {
				tc::for_each(jsclass.m_vecpjsclassSortDependency, [&](SJsClass const* pjsclass) noexcept {
					ForEachChild(*pjsclass);
				});
			}
		);

		std::vector<SJsTypeAlias const*> vecpjstypealiasSorted = SortDeclarationOrder(
			g_setjstypealias,
			[&](SJsTypeAlias const& jstypealias, auto ForEachChild) noexcept {
				ForEachChildTypeNode(jstypealias.m_jtypenode, [&](ts::TypeNode jtypenode) noexcept {
					if(ts::SyntaxKind::TypeReference==jtypenode->kind()) {
						auto jtype = (*g_ojtsTypeChecker)->getTypeFromTypeNode(jtypenode);
						if(auto const ojsym = jtype->aliasSymbol()) {
							if(auto const itjstypealias = tc::cont_find<tc::return_element_or_null>(
								g_setjstypealias,
								FullyQualifiedName(*ojsym)
							)) { // stop dfs when the child class is not part of our source files
								ForEachChild(*itjstypealias);
							}
						}
						if(auto oatypeargs = ts::TypeReference(jtype)->typeArguments()) {
							tc::for_each(*oatypeargs, [&](auto jtype) noexcept {
								if(auto ojsym = OptSymbolOrAliasSymbol(jtype)) {
									if(auto const itjstypealias = tc::cont_find<tc::return_element_or_null>(
										g_setjstypealias,
										FullyQualifiedName(*ojsym)
									)) { // stop dfs when the child class is not part of our source files
										ForEachChild(*itjstypealias);
									}
								}
							});
						}
					}
					return erecurseCONTINUE;
				});
			}
		);

		auto TemplateDecl = [](auto const& strPrefix, auto const& js) noexcept {
			return [&](auto&& sink) noexcept {
				if(!tc::empty(js.m_vectypeparam)) {
					tc::for_each(tc::concat(strPrefix, "template<"), sink);

					tc::for_each(tc::join_separated(
							tc::transform(js.m_vectypeparam,
								[](auto const& typeparam) noexcept {
									return tc_conditional_range(
										etypeparamTYPE==typeparam.m_etypeparam || etypeparamKEYOF == typeparam.m_etypeparam,
										tc::concat("typename ", typeparam.m_strName),
										tc::concat(typeparam.Type(), " ", typeparam.m_strName)
									);
								}
							),
							", "
						),
						sink
					);
					tc::for_each(">\n", sink);
				}
			};
		};

		auto TemplateArgs = [](auto const& js) noexcept {
			return tc_conditional_range(
				!tc::empty(js.m_vectypeparam),
				tc::concat("<", tc::join_separated(tc::transform(js.m_vectypeparam, TC_MEMBER(.m_strName)), ", "),">")
			);
		};

		auto FunctionImpl = [&TemplateDecl](auto&& rngstrNamespace, auto const& CallExpression, SJsFunctionLike const& jsfunctionlike) noexcept {
			auto ojstypenode = ts::SignatureDeclarationBase(jsfunctionlike.m_jsignature->getDeclaration())->type();
			// TODO: Generate overloads when the last argument of jsfunctionlike is variadic https://github.com/think-cell/typescripten/issues/23
			// our output variadic template argument list?
			return tc::concat(
				TemplateDecl("\t", jsfunctionlike),
				"\tinline auto ", std::forward<decltype(rngstrNamespace)>(rngstrNamespace), jsfunctionlike.m_strCppifiedName, "(", jsfunctionlike.CppifiedParametersWithCommentsDef(), ") noexcept {\n",
				tc_conditional_range(
					ojstypenode && ts::SyntaxKind::TypePredicate==(*ojstypenode)->kind(),
					// Functions may be type guards https://www.typescriptlang.org/docs/handbook/advanced-types.html
					// The actual callable JS function printed by CallExpression() returns a bool. The typescript compiler performs a cast when the function returns true.
					// Here we do the same in C++.
					tc::concat(
						"\t\tstd::optional<", MangleType((*g_ojtsTypeChecker)->getTypeFromTypeNode(*ts::TypePredicateNode(*ojstypenode)->type())).m_strWithComments ,"> result;\n"
						"\t\tif(", CallExpression(), ") {\n"
							"\t\t\tresult.emplace(",
								tc_conditional_range(
									ts::SyntaxKind::ThisType==ts::Node(ts::TypePredicateNode(*ojstypenode)->parameterName())->kind(),
									"_this<tc::js::any>()",
									tc::concat(
										"tc::js::any(",
										tc::find_first_if<tc::return_element>(
											jsfunctionlike.m_vecjsparam,
											[&](auto const& jsvariable) noexcept {
												return jsvariable.m_strJsName==tc::explicit_cast<std::string>(ts::idText(ts::TypePredicateNode(*ojstypenode)->parameterName().get<ts::Identifier>()));
											}
										)->m_strCppifiedName,
										")"
									)
								),
							");\n"
						"\t\t}\n"
						"\t\treturn result;\n"
					),
					// Normal function: Just insert function call and optional return
					tc::concat(
						"\t\t",
						tc_conditional_range(
							ts::TypeFlags::Void!=jsfunctionlike.m_jsignature->getReturnType()->flags(),
							"return"
						),
						" ", CallExpression(), ";\n"
					)
				),
				"\t}\n"
			);
		};

		auto ExportFunctionImpl = [&](auto&& rngstrNamespace, SJsFunctionLike const& jsfunctionlike) noexcept {
			return FunctionImpl(
				std::forward<decltype(rngstrNamespace)>(rngstrNamespace),
				[&]() noexcept {
					auto FunctionCall = [&]() noexcept {
						return tc::concat(
							RetrieveSymbolFromCpp(jsfunctionlike.m_jsym), "(",
								tc::join_separated(
									tc::transform(jsfunctionlike.m_vecjsparam, TC_MEMBER(.m_strCppifiedName)),
									", "
								),
							")"
						);
					};
					return tc_conditional_range(
						ts::TypeFlags::Void == jsfunctionlike.m_jsignature->getReturnType()->flags(),
						tc::concat(FunctionCall()),
						tc::concat(
							FunctionCall(), ".template as<", MangleType(jsfunctionlike.m_jsignature->getReturnType()).m_strWithComments, ">()"
						)
					);
				},
				jsfunctionlike
			);
		};

		auto ClassExportTypeParamUsingDecl = [&](auto const& js) noexcept {
			return tc::concat(
				TemplateDecl("\t\t\t", js),
				"\t\t\tusing ",
				js.m_strCppifiedName,
				" = ",
				js.m_strMangledName,
				TemplateArgs(js),
				";\n"
			);
		};

		auto ClassExportTypeUsingDecl = [](auto const& js) noexcept {
			return tc::concat(
				"\t\t\tusing ",
				js.m_strCppifiedName,
				" = ",
				js.m_strMangledName,
				";\n"
			);
		};

		tc::append(std::cout,
			"#include <boost/hana/assert.hpp>\n"
			"#include <boost/hana/integral_constant.hpp>\n"
			"#include <boost/hana/map.hpp>\n"
			"#include <boost/hana/pair.hpp>\n"
			"#include <boost/hana/type.hpp>\n"
			"#include <boost/hana/string.hpp>\n"
			"#include <boost/hana/hash.hpp>\n"
			"#include <boost/hana/at_key.hpp>\n"
			"using namespace boost::hana::literals;\n"
			"#pragma push_macro(\"assert\")\n"
			"#undef assert\n"
			"namespace tc::js_defs {\n",
			tc::join(tc::transform(g_setjsenum, [](SJsEnum const& jsenumEnum) noexcept {
				// We have to mark enums as IsJsIntegralEnum before using in js interop.
				// We have to generate them as enum class even though this is semantically stronger than
				// TypeScript enums actually are. Non-class C++ enum options must be globally unique though
				// and TypeScript enum option names are scoped names like C++ enum class options.
				return tc::concat(
					"\tenum class ", jsenumEnum.m_strMangledName, " {\n",
					tc::join_separated(
						tc::transform(jsenumEnum.m_vecjsenumoption, [&jsenumEnum](SJsEnumOption const& jsenumoption) noexcept {
							return tc::concat(
								"\t\t", jsenumoption.m_strCppifiedName,
								tc_conditional_range(
									jsenumEnum.m_bIsIntegral && !std::holds_alternative<std::monostate>(jsenumoption.m_vardblstrValue),
									tc::concat(" = ", tc::as_dec(tc::explicit_cast<int>(std::get<double>(jsenumoption.m_vardblstrValue))))
								)
							);
						}),
						",\n"
					),
					"\n	};\n"
				);
			})),
			"} // namespace tc::js_defs\n"
			"namespace tc::jst {\n",
			tc::join(tc::transform(g_setjsenum, [](SJsEnum const& jsenumEnum) noexcept {
				// Enums are declared outside of the _jsall class because we have to mark them as IsJsIntegralEnum
				// before using in js interop.
				return tc_conditional_range(
					jsenumEnum.m_bIsIntegral,
					tc::concat(
						"\ttemplate<> struct IsJsIntegralEnum<js_defs::", jsenumEnum.m_strMangledName, "> : std::true_type {};\n"
					),
					tc::concat(
						"template<> struct IsJsHeterogeneousEnum<js_defs::", jsenumEnum.m_strMangledName, "> : std::true_type {\n"
						"\tstatic inline auto const& Values() {\n"
						"\t\tusing E = js_defs::", jsenumEnum.m_strMangledName, ";\n"
						"\t\tstatic tc::unordered_map<E, js::any> vals{\n",
						tc::join_separated(
							tc::transform(
								tc::filter(
									jsenumEnum.m_vecjsenumoption,
									[](SJsEnumOption const& jsenumoption) noexcept { return !std::holds_alternative<std::monostate>(jsenumoption.m_vardblstrValue); }
								),
								[](SJsEnumOption const& jsenumoption) noexcept {
									return tc::concat(
										"\t\t\t{E::", jsenumoption.m_strCppifiedName, ", ",
										tc::visit(jsenumoption.m_vardblstrValue,
											[](double dblValue) noexcept {
												// TODO: std::to_string because of floating-point numbers. May be not enough precision.
												return tc::make_str("tc::js::any(", std::to_string(dblValue), ")");
											},
											[](std::string const& strValue) noexcept {
												return tc::make_str("tc::js::string(\"", strValue, "\")");
											},
											[](std::monostate const&) noexcept {
												_ASSERTFALSE;
												return tc::make_str("");
											}
										),
										"}"
									);
								}
							),
							",\n"
						),
						"\n"
						"\t\t};\n"
						"\t\treturn vals;\n"
						"\t}\n"
						"};\n"
					)
				);
			})),
			"} // namespace tc::jst\n"
			"namespace tc::js_defs {\n"
			"\tusing namespace jst; // no ADL\n",
			tc::join(tc::transform(vecpjsclassSorted, [&](SJsClass const* pjsclass) noexcept {
				return tc::concat(
					TemplateDecl("\t", *pjsclass),
					"\tstruct _impl", pjsclass->m_strMangledName, ";\n",
					TemplateDecl("\t", *pjsclass),
					"\tusing ",
					pjsclass->m_strMangledName,
					" = ref<_impl", pjsclass->m_strMangledName,
					TemplateArgs(*pjsclass),
					">;\n"
				);
			})),
			tc::join(tc::transform(vecpjstypealiasSorted, [&](SJsTypeAlias const* pjtypealias) noexcept {
				return tc::explicit_cast<std::string>(
					tc::concat(
						TemplateDecl("\t", *pjtypealias),
						"\tusing ", pjtypealias->m_strMangledName, " = ", pjtypealias->MangleType().m_strWithComments,
						";\n"
					)
				);
			})),
			tc::join(tc::transform(vecpjsclassSorted, [&](SJsClass const* pjsclass) noexcept {
				return tc::make_str<char>(
					TemplateDecl("\t", *pjsclass),
					"\tstruct _impl", pjsclass->m_strMangledName,
					" : ",
					tc_conditional_range(
						tc::empty(pjsclass->m_vecmtBaseClass),
						"virtual object_base",
						tc::join_separated(
							tc::transform(
								pjsclass->m_vecmtBaseClass,
								[](auto const& mt) noexcept {
									return tc::concat("virtual _impl", mt.m_strCppCanonized);
								}
							),
							", "
						)
					),
					" {\n",
					"\t\tstruct _tcjs_definitions {\n",
					tc_conditional_range(
						!tc::empty((*g_ojtsTypeChecker)->getPropertiesOfType(pjsclass->m_jtype)),
						tc::concat(
							"\t\t\ttemplate<typename __TYPESCRIPTEN_DUMMY_ARG = tc::js::any>\n"
							"\t\t\tstatic auto constexpr keyof() noexcept { return boost::hana::make_map(\n"
							// We put the keyof map in a templated method to reduce compile times.
							// If the return value depends on the (defaulted) template argument, the
							// compiler does not need to compute the return type unless keyof() is
							// actually called. This reduces compile times by 90%.
							"\t\t\t\tboost::hana::make_pair(\"__typescripten_dummy_key\"_s, boost::hana::type_c<__TYPESCRIPTEN_DUMMY_ARG>),\n",
							tc::join_separated(
								tc::transform(
									// We enumerate all properties of pjsclass, including properties of derived classes
									// TODO: keyof T also considers member functions as key
									(*g_ojtsTypeChecker)->getPropertiesOfType(pjsclass->m_jtype),
									[&](auto const& jsym) noexcept {
										return tc::concat(
											"\t\t\t\tboost::hana::make_pair(\"", tc::explicit_cast<std::string>(jsym->getName()), "\"_s, "
											"boost::hana::type_c<",
												[&]() noexcept {
													// This resolves the type of jsym in the context of pjsclass, i.e.,
													// interface B<T> {
													// 	t: T;
													// }
													// interface A extends B<string> {}
													//
													// A has a property t of type "string".
													//
													auto jtype = (*g_ojtsTypeChecker)->getTypeOfSymbolAtLocation(jsym, tc::front(*pjsclass->m_jsym->declarations()));
													if(static_cast<bool>(ts::TypeFlags::TypeParameter&jtype->getFlags())) {
														STypeParameter typeparam(ts::TypeParameterDeclaration(tc::front(*(*jtype->getSymbol())->declarations())));
														if(etypeparamNUMBER==typeparam.m_etypeparam) {
															return tc::make_str("number");
														} else if(etypeparamENUM==typeparam.m_etypeparam) {
															jtype = *typeparam.m_ojtype;
														}
													}
													return MangleType(jtype).m_strWithComments;
												}(),
											">)"
										);
									}
								),
								",\n"
							),
							"\n\t\t\t); }\n"
						)
					),
					tc::join(tc::transform(
						pjsclass->m_vecjsenumExport,
						ClassExportTypeUsingDecl
					)),
					tc::join(tc::transform(
						pjsclass->m_vecjsclassExport,
						ClassExportTypeParamUsingDecl
					)),
					tc::join(tc::transform(
						pjsclass->m_vecjstypealiasExport,
						ClassExportTypeParamUsingDecl
					)),
					tc::join(tc::transform(
						pjsclass->m_vecjsfunctionlikeExport,
						[&](SJsFunctionLike const& jsfunctionlike) noexcept {
							return tc::concat(
								TemplateDecl("\t\t\t", jsfunctionlike),
								"\t\t\tstatic auto ", jsfunctionlike.m_strCppifiedName, "(", jsfunctionlike.CppifiedParametersWithCommentsDecl(), ") noexcept;\n"
							);
						}
					)),
					tc::join(tc::transform(
						pjsclass->m_vecjsvariablelikeExport,
						[&](SJsVariableLike const& jsvariablelikeVariable) noexcept {
							return tc::concat(
								"\t\t\tstatic auto ", jsvariablelikeVariable.m_strCppifiedName, "() noexcept;\n",
								tc_conditional_range(
									jsvariablelikeVariable.m_bReadonly,
									"",
									tc::concat(
										"\t\t\tstatic void ", jsvariablelikeVariable.m_strCppifiedName, "(", jsvariablelikeVariable.MangleType(pjsclass->m_vectypeparam).m_strWithComments, " v) noexcept;\n"
									)
								)
							);
						}
					)),
					"\t\t};\n",
					tc::join(tc::transform(
						pjsclass->m_vecjsvariablelikeProperty,
						[&](SJsVariableLike const& jsvariablelikeProperty) noexcept {
							return tc::concat(
								"\t\tauto ", jsvariablelikeProperty.m_strCppifiedName, "() noexcept;\n",
								tc_conditional_range(
									jsvariablelikeProperty.m_bReadonly,
									"",
									tc::concat(
										"\t\tvoid ", jsvariablelikeProperty.m_strCppifiedName, "(", jsvariablelikeProperty.MangleType(pjsclass->m_vectypeparam).m_strWithComments, " v) noexcept;\n"
									)
								)
							);
						}
					)),
					tc::join(tc::transform(
						pjsclass->m_vecjsfunctionlikeCtor,
						[](SJsFunctionLike const& jsfunctionlike) noexcept {
							return tc::concat(
								"\t\tstatic auto _tcjs_construct(", jsfunctionlike.CppifiedParametersWithCommentsDecl(), ") noexcept;\n"
							);
						}
					)),
					tc_conditional_range(
						pjsclass->m_bHasImplicitDefaultConstructor,
						"\t\tstatic auto _tcjs_construct() noexcept;\n"
					),
					tc::join(tc::transform(
						pjsclass->m_vecjsfunctionlikeMethod,
						[&](SJsFunctionLike const& jsfunctionlike) noexcept {
							return tc::concat(
								TemplateDecl("\t\t", jsfunctionlike),
								"\t\tauto ", jsfunctionlike.m_strCppifiedName, "(", jsfunctionlike.CppifiedParametersWithCommentsDecl(), ") noexcept;\n"
							);
						}
					)),
					"\t};\n"
				);
			})),
			tc::join(tc::transform(vecpjsclassSorted, [&](SJsClass const* pjsclass) noexcept {
				auto const strClassNamespace = tc::concat("_impl", pjsclass->m_strMangledName, TemplateArgs(*pjsclass), "::");
				auto const strClassInstanceRetrieve = RetrieveSymbolFromCpp(pjsclass->m_jsym);

				return tc::make_str<char>(
					tc::join(tc::transform(
						pjsclass->m_vecjsfunctionlikeExport,
						[&](SJsFunctionLike const& jsfunctionlike) noexcept {
							return tc::concat(
								TemplateDecl("\t", *pjsclass),
								ExportFunctionImpl(tc::concat(strClassNamespace, "_tcjs_definitions::"), jsfunctionlike)
							);
						}
					)),
					tc::join(tc::transform(
						pjsclass->m_vecjsvariablelikeExport,
						[&](SJsVariableLike const& jsvariablelikeVariable) noexcept {
							return tc::concat(
								TemplateDecl("\t", *pjsclass),
								"\tinline auto ", strClassNamespace, "_tcjs_definitions::", jsvariablelikeVariable.m_strCppifiedName, "() noexcept "
								"{ return ", strClassInstanceRetrieve, "[\"", jsvariablelikeVariable.m_strJsName, "\"].template as<", jsvariablelikeVariable.MangleType(pjsclass->m_vectypeparam).m_strWithComments, ">(); }\n",
								tc_conditional_range(
									!jsvariablelikeVariable.m_bReadonly,
									tc::concat(
										TemplateDecl("\t", *pjsclass),
										"\tinline void ", strClassNamespace, "_tcjs_definitions::", jsvariablelikeVariable.m_strCppifiedName, "(", jsvariablelikeVariable.MangleType(pjsclass->m_vectypeparam).m_strWithComments, " v) noexcept "
										"{ ", strClassInstanceRetrieve, ".set(\"", jsvariablelikeVariable.m_strJsName, "\", v); }\n"
									)
								)
							);
						}
					)),
					tc::join(tc::transform(
						pjsclass->m_vecjsvariablelikeProperty,
						[&](SJsVariableLike const& jsvariablelikeProperty) noexcept {
							return tc::concat(
								TemplateDecl("\t", *pjsclass),
								"\tinline auto ", strClassNamespace, jsvariablelikeProperty.m_strCppifiedName, "() noexcept "
								"{ return this->template _getProperty<", jsvariablelikeProperty.MangleType(pjsclass->m_vectypeparam).m_strWithComments, ">(\"", jsvariablelikeProperty.m_strJsName, "\"); }\n",
								tc_conditional_range(
									!jsvariablelikeProperty.m_bReadonly,
									tc::concat(
										TemplateDecl("\t", *pjsclass),
										"\tinline void ", strClassNamespace, jsvariablelikeProperty.m_strCppifiedName, "(", jsvariablelikeProperty.MangleType(pjsclass->m_vectypeparam).m_strWithComments, " v) noexcept "
										"{ this->template _setProperty(\"", jsvariablelikeProperty.m_strJsName, "\", v); }\n"
									)
								)
							);
						}
					)),
					tc::join(tc::transform(
						pjsclass->m_vecjsfunctionlikeCtor,
						[&](SJsFunctionLike const& jsfunctionlike) noexcept {
							return tc::concat(
								TemplateDecl("\t", *pjsclass),
								"\tinline auto ", strClassNamespace, "_tcjs_construct(", jsfunctionlike.CppifiedParametersWithCommentsDef(), ") noexcept {\n"
									"\t\treturn ", pjsclass->m_strMangledName, TemplateArgs(*pjsclass), "(",
										strClassInstanceRetrieve, ".new_(",
											tc::join_separated(tc::transform(jsfunctionlike.m_vecjsparam, TC_MEMBER(.m_strCppifiedName)), ", "),
										"));\n"
								"\t}\n"
							);
						}
					)),
					tc_conditional_range(
						pjsclass->m_bHasImplicitDefaultConstructor,
						tc::concat(
							TemplateDecl("\t", *pjsclass),
							"\tinline auto ", strClassNamespace, "_tcjs_construct() noexcept {\n"
							"\t\treturn ",
								tc_conditional_range(
									static_cast<bool>(ts::SymbolFlags::Interface & pjsclass->m_jsym->getFlags()),
									"emscripten::val::object()",
									tc::concat(pjsclass->m_strMangledName, TemplateArgs(*pjsclass), "(", strClassInstanceRetrieve, ".new_())")
								),
								";\n"
							"\t}\n"
						)
					),
					tc::join(tc::transform(
						pjsclass->m_vecjsfunctionlikeMethod,
						[&](SJsFunctionLike const& jsfunctionlike) noexcept {
							return tc::concat(
								TemplateDecl("\t", *pjsclass),
								FunctionImpl(
									strClassNamespace,
									[&]() noexcept {
										return tc::concat(
											tc_conditional_range(
												jsfunctionlike.m_bIndexSignature,
												"this->template _getProperty<",
												"this->template _call<"
											),
												MangleType(jsfunctionlike.m_jsignature->getReturnType()).m_strWithComments,
											">(",
											tc_conditional_range(
												jsfunctionlike.m_bIndexSignature,
												tc::join_separated(
													tc::transform(jsfunctionlike.m_vecjsparam, TC_MEMBER(.m_strCppifiedName)),
													", "
												),
												tc::join_separated(
													tc::concat(
														tc::single(tc::concat("\"", tc::explicit_cast<std::string>(jsfunctionlike.m_jsym->getName()), "\"")),
														tc::transform(jsfunctionlike.m_vecjsparam, TC_MEMBER(.m_strCppifiedName))
													),
													", "
												)
											),
											")"
										);
									},
									jsfunctionlike
								)
							);
						}
					))
				);
			}))
		);

		tc::append(std::cout,
			tc::join(tc::transform(
				scopeGlobal.m_vecjsfunctionlikeExport,
				[&](SJsFunctionLike const& jsfunctionlike) noexcept {
					return ExportFunctionImpl(tc::empty_range(), jsfunctionlike);
				}
			)),
			tc::join(tc::transform(
				scopeGlobal.m_vecjsvariablelikeExport,
				[&](SJsVariableLike const& jsvariablelikeVariable) noexcept {
					return tc::concat(
						"\tinline auto ", jsvariablelikeVariable.m_strCppifiedName, "() noexcept "
						"{ return emscripten::val::global(\"", jsvariablelikeVariable.m_strJsName, "\").template as<", jsvariablelikeVariable.MangleType(tc::make_empty_range<STypeParameter>()).m_strWithComments, ">(); }\n",
						tc_conditional_range(
							jsvariablelikeVariable.m_bReadonly,
							"",
							tc::concat(
								"\tinline void ", jsvariablelikeVariable.m_strCppifiedName, "(", jsvariablelikeVariable.MangleType(tc::make_empty_range<STypeParameter>()).m_strWithComments, " v) noexcept "
								"{ emscripten::val::global().set(\"", jsvariablelikeVariable.m_strJsName, "\", v); }\n"
							)
						)
					);
				}
			)),
			"}; // namespace tc::js_defs\n"
			"namespace tc::js {\n"
		);

		auto GlobalExportTypeParamUsingDecl = [&](auto const& js) noexcept {
			return tc::concat(
				TemplateDecl("\t\t\t", js),
				"\t\t\tusing ",
				js.m_strCppifiedName,
				" = js_defs::",
				js.m_strMangledName,
				TemplateArgs(js),
				";\n"
			);
		};

		auto GlobalExportTypeUsingDecl = [](auto const& js) noexcept {
			return tc::concat(
				"\t\t\tusing ",
				js.m_strCppifiedName,
				" = js_defs::",
				js.m_strMangledName,
				";\n"
			);
		};

		tc::append(std::cout,
			tc::join(tc::transform(
				scopeGlobal.m_vecjsenumExport,
				GlobalExportTypeUsingDecl
			)),
			tc::join(tc::transform(
				scopeGlobal.m_vecjsclassExport,
				GlobalExportTypeParamUsingDecl
			)),
			tc::join(tc::transform(
				scopeGlobal.m_vecjstypealiasExport,
				GlobalExportTypeParamUsingDecl
			)),
			tc::join(tc::transform(
				scopeGlobal.m_vecjsfunctionlikeExport,
				[](SJsFunctionLike const& jsfunctionlike) noexcept {
					return tc::concat("\tusing js_defs::", jsfunctionlike.m_strCppifiedName, ";\n");
				}
			)),
			tc::join(tc::transform(
				scopeGlobal.m_vecjsvariablelikeExport,
				[](SJsVariableLike const& jsvariablelikeVariable) noexcept {
					return tc::concat("\tusing js_defs::", jsvariablelikeVariable.m_strCppifiedName, ";\n");
				}
			)),
			"} // namespace tc::js\n"
			"#pragma pop_macro(\"assert\")\n"
		);
	}
}

int main(int cArgs, char* apszArgs[]) {
#ifdef DEBUG_DEVTOOLS
	// See README.md for an explanation on how to setup interactive debugging with Chrome DevTools
	static struct Callback final {
		ts::CompilerOptions m_jtsCompilerOptions;

		Callback() noexcept
			: m_jtsCompilerOptions(jst::create_js_object)
		{
			m_jtsCompilerOptions->strict(true);
			m_jtsCompilerOptions->target(ts::ScriptTarget::ES5);
			m_jtsCompilerOptions->module(ts::ModuleKind::CommonJS);
		}

		TC_JS_MEMBER_FUNCTION(Callback, WithDefaultMap, void, (js::Map<js::string, js::string> mapstrstr)) {
			mapstrstr->set(
				js::string("index.ts"),
				js::string(emscripten::val::global("document").call<emscripten::val>("getElementById", emscripten::val("text"))["innerHTML"])
			);

			auto rngstrFileNames = tc::single("index.ts");

			auto const jtsHost = tc::js::tsvfs::createVirtualCompilerHost(
				tc::js::tsvfs::createSystem(mapstrstr),
				m_jtsCompilerOptions,
				tc::js::any(emscripten::val::global("ts"))
			);
			auto const jtsProgram = ts::createProgram(ReadonlyArray<string>(create_js_object, rngstrFileNames), m_jtsCompilerOptions, ts::CompilerHost(jtsHost.getEmval()["compilerHost"]));
			CompileProgram(jtsProgram, rngstrFileNames);
		}
	} cb;

	tc::js::tsvfs::createDefaultMapFromCDN()(cb.m_jtsCompilerOptions, ts::version(), true, tc::js::any(emscripten::val::global("ts")), js::undefined(), js::undefined(), js::undefined())->then(cb.WithDefaultMap);
#else
	if(cArgs < 2) {
		tc::append(
			std::cerr,
			"Not enough arguments\n"
			"Syntax: node typescriptenc.js <TypeScript interface definition.d.ts>\n"
		);
		return 1;
	}

	// TODO: Add command line parameter to ignore symbols
	// These are all part of lib.es5.d.ts
	tc::cont_must_emplace(g_setstrIgnoredSymbols, "ClassDecorator");
	tc::cont_must_emplace(g_setstrIgnoredSymbols, "MethodDecorator");
	tc::cont_must_emplace(g_setstrIgnoredSymbols, "IDBValidKey");

	auto const rngstrFileNames = tc::counted(boost::next(apszArgs), cArgs - 1);
	tc::for_each(rngstrFileNames, [](tc::ptr_range<char> rngch) noexcept {
		tc::for_each(rngch, [](auto& ch) noexcept {
			if('\\'==ch) ch = '/'; // typescript createProgram does not support backslashes
		});
	});

	ts::CompilerOptions const jtsCompilerOptions(create_js_object);
	jtsCompilerOptions->strict(true);
	jtsCompilerOptions->target(ts::ScriptTarget::ES5);
	jtsCompilerOptions->module(ts::ModuleKind::CommonJS);

	ts::Program const jtsProgram = ts::createProgram(tc::jst::make_ReadonlyArray<js::string>(rngstrFileNames), jtsCompilerOptions);
	{
		auto const jtsReadOnlyArrayDiagnostics = ts::getPreEmitDiagnostics(jtsProgram);
		if(!tc::empty(jtsReadOnlyArrayDiagnostics)) {
			tc::append(
				std::cerr,
				tc::explicit_cast<std::string>(
					ts::formatDiagnosticsWithColorAndContext(jtsReadOnlyArrayDiagnostics, ts::FormatDiagnosticsHost(ts::createCompilerHost(jtsCompilerOptions).getEmval()))
				)
			);
			return 1;
		}
	}

	CompileProgram(jtsProgram, rngstrFileNames);
#endif
}

max_stars_repo_name: think-cell/typescripten

max_issues_repo_name: think-cell/typescripten

max_forks_repo_name: think-cell/typescripten


text:
// -*- C++ -*-
//
// Package:     Core
// Class  :     expressionFormatHelpers
//
// Implementation:
//     <Notes on implementation>
//
// Original Author:  Chris Jones
//         Created:  Fri Aug 22 12:25:04 EDT 2008
//

// system include files
#include <boost/regex.hpp>

// user include files
#include "Fireworks/Core/src/expressionFormatHelpers.h"

//
// constants, enums and typedefs
//

namespace fireworks {
  namespace expression {
    std::string oldToNewFormat(const std::string& iExpression) {
      //Backwards compatibility with old format: If find a $. or a () just remove them
      const std::string variable;
      static boost::regex const reVarName("(\\$\\.)|(\\(\\))");

      return boost::regex_replace(iExpression, reVarName, variable);
    }

    long indexFromNewFormatToOldFormat(const std::string& iNewFormat,
                                       long iNewFormatIndex,
                                       const std::string& iOldFormat) {
      if (iNewFormat.substr(0, iNewFormatIndex) == iOldFormat.substr(0, iNewFormatIndex)) {
        return iNewFormatIndex;
      }
      assert(iNewFormat.size() < iOldFormat.size());
      std::string::const_iterator itNew = iNewFormat.begin(), itOld = iOldFormat.begin(), itNewEnd = iNewFormat.end();
      for (; itNew != itNewEnd && itNew - iNewFormat.begin() < iNewFormatIndex; ++itNew, ++itOld) {
        while (*itNew != *itOld) {
          assert(itOld != iOldFormat.end());
          ++itOld;
        }
      }
      return itOld - iOldFormat.begin();
    }
  }  // namespace expression
}  // namespace fireworks

ext: cc

max_stars_repo_name: ckamtsikis/cmssw

max_issues_repo_name: ckamtsikis/cmssw

max_forks_repo_name: ckamtsikis/cmssw


text:
#ifndef BZ_EXPR_CC
#define BZ_EXPR_CC

#include <blitz/array/expr.h>

BZ_NAMESPACE(blitz)

template<typename P_numtype>
inline RectDomain<12>
_bz_ArrayExprConstant<P_numtype>::domain() const
{
  TinyVector<int, 12> lb(lbound(0)), ub(ubound(0));
  return RectDomain<12>(lb,ub);
}

BZ_NAMESPACE_END

#endif

max_stars_repo_name: MSV-Project/IBAMR

max_issues_repo_name: MSV-Project/IBAMR

max_forks_repo_name: MSV-Project/IBAMR


text:
#include "Common.h"
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/tcp.h>
#include <boost/shared_ptr.hpp>
#include <boost/foreach.hpp>
#include "SSEClient.h"
#include "HTTPRequest.h"

/**
 Constructor.
 @param fd Client socket file descriptor.
 @param csin Client sockaddr_in structure.
*/
SSEClient::SSEClient(int fd, struct sockaddr_in* csin) {
  _fd = fd;
  _dead = false;

   memcpy(&_csin, csin, sizeof(struct sockaddr_in));
  DLOG(INFO) << "Initialized client with IP: " << GetIP();

  m_httpReq = boost::shared_ptr<HTTPRequest>(new HTTPRequest());

  int flag = 1;

  _isIdFiltered = false;
  _isEventFiltered = false;

  // Set KEEPALIVE on socket.
  setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (char*)&flag, sizeof(int));

  // If we have TCP_USER_TIMEOUT set it to 10 seconds.
  #ifdef TCP_USER_TIMEOUT
  int timeout = 10000;
  setsockopt (fd, SOL_TCP, TCP_USER_TIMEOUT, (char*) &timeout, sizeof (timeout));
  #endif

  // Set TCP_NODELAY on socket.
  setsockopt(Getfd(), IPPROTO_TCP, TCP_NODELAY, (char*)&flag, sizeof(int));
}

/**
  Destructor.
*/
void SSEClient::Destroy() {
  delete(this);
}

/*
 Cut off @param bytes from our internal sendbuffer.
 @param bytes Number of bytes to cut off.
*/
size_t SSEClient::_prune_sendbuffer_bytes(size_t bytes) {

  if (_sndBuf.length() < 1) return 0;
  if (bytes > _sndBuf.size()) _sndBuf.clear();

  _sndBuf = _sndBuf.substr(bytes, _sndBuf.length() - bytes);

  // Return elements present in _sndBuf after removal.
  return _sndBuf.length();
}

/*
  Write single element in the send buffer using write().
*/
int SSEClient::_write_sndbuf() {
  int ret = 0;

  if (_sndBuf.length() < 1) return 0;
  ret = write(_fd, _sndBuf.c_str(), _sndBuf.length());

  if (ret <= 0) {
    DLOG(INFO) << GetIP() << ": write flush error: " << strerror(errno);
  } else if ((unsigned int)ret < _sndBuf.length()) {
    _prune_sendbuffer_bytes(ret);
    DLOG(INFO) << GetIP() << ": Could not write() entire buffer, wrote " << ret << " of " << _sndBuf.length() << " bytes.";
  } else {
    _sndBuf.clear();
  }

  return ret;
}

/*
  Flush data in the sendbuffer.
*/
int SSEClient::Flush() {
  boost::mutex::scoped_lock lock(_sndBufLock);
  return _write_sndbuf();
}

/**
 Sends data to client.
 @param data String buffer to send.
*/
int SSEClient::Send(const string &data, bool flush) {
  if (!isFilterAcceptable(data)) return 0;

  _sndBufLock.lock();
  _sndBuf.append(data);
  _sndBufLock.unlock();

  if (flush) Flush();
  return _sndBuf.length();
}

/**
 Read data from client.
 @param buf Pointer to buffer where data should be read into.
 @param len Bytes to read.
*/
size_t SSEClient::Read(void* buf, int len) {
  return read(_fd, buf, len);
}

/**
  Destructor.
*/
SSEClient::~SSEClient() {
  DLOG(INFO) << "Destructor called for client with IP: " << GetIP();
  if (!IsDead()) close(_fd);
}

/**
 Returns the client file descriptor.
*/
int SSEClient::Getfd() {
  return _fd;
}

/**
  Returns the client's ip address as a string.
*/
const string SSEClient::GetIP() {
  char ip[32];
  inet_ntop(AF_INET, &_csin.sin_addr, (char*)&ip, 32);

  return ip;
}

/*
  Get clients sockaddr.
*/
uint32_t SSEClient::GetSockAddr() {
  return _csin.sin_addr.s_addr;
}

/*
 Get the HTTPRequest the client was initiated with.
*/
HTTPRequest* SSEClient::GetHttpReq() {
  return m_httpReq.get();
}

/*
  Delete the stored initial HTTPRequest.
*/
void SSEClient::DeleteHttpReq() {
  m_httpReq.reset();
}

/*
 Mark client as dead and ready for removal.
*/
void SSEClient::MarkAsDead() {
  _dead = true;
  close(_fd);
}

/*
 Returns wether this client is dead or not.
*/
bool SSEClient::IsDead() {
  return _dead;
}

/*
 Extract SSE-field from data.
 @param data Search string.
 @param fieldName field to extract.
*/
const string SSEClient::_get_sse_field(const string& data, const string& fieldName) {
  size_t field_pos = data.find(fieldName + ": ");
  size_t field_val_offset;
  string field_val;

  if (field_pos != string::npos) {
    // Add +2 to the offset to take account for ": ".
    field_val_offset = fieldName.length() + 2;

    size_t field_nl_pos = data.find_first_of('\n', field_pos);
    if (field_nl_pos != string::npos) {
      field_val = data.substr(field_pos+field_val_offset, field_nl_pos-field_val_offset);
    }
  }

  return field_val;
}

/*
 Check if client is subscribed to a certain event.
 @param key Subscription key.
 @param type Subscription type.
*/
bool SSEClient::isSubscribed(const string key, SubscriptionType type) {
 BOOST_FOREACH(const SubscriptionElement& subscription, _subscriptions) {
    if (subscription.type == type && (subscription.key.compare(0, subscription.key.length(), key) == 0)) {
      return true;
    }
  }

 return false;
}

/*
  Subscripe to a certain event and type.
  @param key Subscription key.
  @param type Subscription type.
*/
void SSEClient::Subscribe(const string key, SubscriptionType type) {
  SubscriptionElement subscription;
  subscription.key  = key;
  subscription.type = type;
  if (type == SUBSCRIPTION_ID) _isIdFiltered = true;
  if (type == SUBSCRIPTION_EVENT_TYPE) _isEventFiltered = true;
  _subscriptions.push_back(subscription);
}

/*
  Check if data is allowed to pass our subscriptions.
  @param data Buffer to validate.
*/
bool SSEClient::isFilterAcceptable(const string& data) {
  // No filters defined.
  if (_subscriptions.size() < 1) return true;

  // Only filter payloads having the "data: " field set.
  if ((data.compare(0, 6, "data: ") != 0) &&
      (data.find("\ndata: ") == string::npos)) {
    return true;
  }

  // Validate id filters if we have any.
  if (_isIdFiltered) {
    string eventId = _get_sse_field(data, "id");
    if (eventId.empty() || !isSubscribed(eventId, SUBSCRIPTION_ID)) return false;
  }

  // Validate event filters if we have any.
  if (_isEventFiltered) {
    string eventType = _get_sse_field(data, "event");
    if (eventType.empty() || !isSubscribed(eventType, SUBSCRIPTION_EVENT_TYPE)) return false;
  }

  return true;
}

ext: cpp

max_stars_repo_name: Competec/ssehub

max_issues_repo_name: Competec/ssehub

max_forks_repo_name: Competec/ssehub


text:
//  (C) Copyright Gennadiy Rozental 2011-2012.
//  Distributed under the Boost Software License, Version 1.0.
//  (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

//  See http://www.boost.org/libs/test for the library home page.
//
//  File        : $RCSfile$
//
//  Version     : $Revision: 74640 $
//
//  Description : defines fixture interface and object makers
// ***************************************************************************

#ifndef BOOST_TEST_TREE_FIXTURE_HPP_100311GER
#define BOOST_TEST_TREE_FIXTURE_HPP_100311GER

// Boost.Test
#include <boost/test/detail/config.hpp>

// Boost
#include <boost/shared_ptr.hpp>
#include <boost/function/function0.hpp>

#include <boost/test/detail/suppress_warnings.hpp>

//____________________________________________________________________________//

namespace boost {
namespace unit_test {

// ************************************************************************** //
// **************               test_unit_fixture              ************** //
// ************************************************************************** //

class BOOST_TEST_DECL test_unit_fixture {
public:
    virtual ~test_unit_fixture() {}

    // Fixture interface
    virtual void    setup() = 0;
    virtual void    teardown() = 0;
};

typedef shared_ptr<test_unit_fixture> test_unit_fixture_ptr;

// ************************************************************************** //
// **************              class_based_fixture             ************** //
// ************************************************************************** //

template<typename F>
class class_based_fixture : public test_unit_fixture {
public:
    // Constructor
    class_based_fixture() : m_inst( 0 ) {}

private:
    // Fixture interface
    virtual void    setup()         { m_inst = new F; }
    virtual void    teardown()      { delete m_inst; }

    // Data members
    F*              m_inst;
};

// ************************************************************************** //
// **************            function_based_fixture            ************** //
// ************************************************************************** //

class function_based_fixture : public test_unit_fixture {
public:
    // Constructor
    function_based_fixture( boost::function<void ()> const& setup, boost::function<void ()> const& teardown )
    : m_setup( setup )
    , m_teardown( teardown )
    {
    }

private:
    // Fixture interface
    virtual void    setup()         { if( m_setup ) m_setup(); }
    virtual void    teardown()      { if( m_teardown ) m_teardown(); }

    // Data members
    boost::function<void ()>    m_setup;
    boost::function<void ()>    m_teardown;
};

} // namespace unit_test
} // namespace boost

#include <boost/test/detail/enable_warnings.hpp>

#endif // BOOST_TEST_TREE_FIXTURE_HPP_100311GER

ext: hpp

max_stars_repo_name: juslee/boost-svn

max_issues_repo_name: datacratic/boost-svn

max_forks_repo_name: datacratic/boost-svn


text:
//==============================================================================
//         Copyright 2003 - 2011 LASMEA UMR 6602 CNRS/Univ. Clermont II
//         Copyright 2009 - 2011 LRI    UMR 8623 CNRS/Univ Paris Sud XI
//
//          Distributed under the Boost Software License, Version 1.0.
//                 See accompanying file LICENSE.txt or copy at
//                     http://www.boost.org/LICENSE_1_0.txt
//==============================================================================
#ifndef NT2_OPERATOR_FUNCTIONS_COMPLEX_GENERIC_MULTIPLIES_HPP_INCLUDED
#define NT2_OPERATOR_FUNCTIONS_COMPLEX_GENERIC_MULTIPLIES_HPP_INCLUDED

#include <nt2/operator/functions/multiplies.hpp>
#include <nt2/include/functions/real.hpp>
#include <nt2/include/functions/imag.hpp>
#include <nt2/include/functions/pure.hpp>
#include <nt2/include/functions/simd/minus.hpp>
#include <nt2/include/functions/simd/unary_minus.hpp>
#include <nt2/include/functions/simd/any.hpp>
#include <nt2/include/functions/fma.hpp>
#include <nt2/include/functions/simd/all.hpp>
#include <nt2/include/functions/simd/is_nez.hpp>
#include <nt2/include/functions/simd/is_invalid.hpp>
#include <nt2/include/functions/logical_or.hpp>
#include <nt2/include/functions/logical_and.hpp>
#include <nt2/include/functions/logical_andnot.hpp>
#include <nt2/include/functions/if_else.hpp>
#include <nt2/include/functions/if_zero_else.hpp>
#include <nt2/include/functions/if_else_zero.hpp>
#include <nt2/include/functions/is_finite.hpp>
#include <nt2/include/functions/is_eqz.hpp>
#include <nt2/include/functions/is_real.hpp>
#include <nt2/include/functions/is_imag.hpp>
#include <nt2/include/functions/simd/mul_i.hpp>
#include <nt2/include/functions/bitwise_cast.hpp>
#include <nt2/include/constants/zero.hpp>
#include <nt2/include/constants/nan.hpp>
#include <nt2/sdk/complex/hierarchy.hpp>
#include <nt2/sdk/complex/meta/as_real.hpp>
#include <nt2/sdk/complex/meta/as_dry.hpp>
#include <nt2/sdk/meta/as_logical.hpp>
#include <boost/simd/sdk/config.hpp>

namespace boost { namespace simd { namespace ext
{
  // complex/complex
  BOOST_DISPATCH_IMPLEMENT  ( multiplies_, tag::cpu_, (A0)
                            , ((generic_< complex_< arithmetic_<A0> > >))
                              ((generic_< complex_< arithmetic_<A0> > >))
                            )
  {
    typedef A0 result_type;
    NT2_FUNCTOR_CALL_REPEAT(2)
    {
      typedef typename nt2::meta::as_real<A0>::type r_type;
      const r_type a = nt2::real(a0);
      const r_type b = nt2::imag(a0);
      const r_type c = nt2::real(a1);
      const r_type d = nt2::imag(a1);
      result_type r(fma(a,c,-b*d), fma(a,d,b*c));
#ifndef BOOST_SIMD_NO_INVALIDS
      typedef typename meta::as_logical<r_type>::type l_type;
      l_type test = is_finite(r);
      if (nt2::all(test)) return r;
      l_type cur  = nt2::logical_andnot(is_real(a0), test);
      if (nt2::any(cur))
      {
        r = if_else(cur, nt2::multiplies(a, a1), r);
        test = logical_or(test, cur);
        if (nt2::all(test)) return r;
      }
      cur = nt2::logical_andnot(is_imag(a0), test);
      if (nt2::any(cur))
      {
        r = if_else(cur, nt2::mul_i(nt2::multiplies(b, a1)), r);
        test = logical_or(test, cur);
        if (nt2::all(test)) return r;
      }
      cur = nt2::logical_andnot(is_real(a1), test);
      if (nt2::any(cur))
      {
        r = if_else(cur, nt2::multiplies(c, a0), r);
        test = logical_or(test, cur);
        if (nt2::all(test)) return r;
      }
      cur = nt2::logical_andnot(is_imag(a1), test);
      if (nt2::any(cur))
      {
        r = if_else(cur, nt2::mul_i(nt2::multiplies(d, a0)), r);
        test = logical_or(test, cur);
        if (nt2::all(test)) return r;
      }
 #endif
      return r;
    }
  };

  // complex/real
  BOOST_DISPATCH_IMPLEMENT  ( multiplies_, tag::cpu_, (A0)(A1)
                            , ((generic_< arithmetic_<A0> >))
                              ((generic_< complex_< arithmetic_<A1> > >))
                            )
  {
    typedef A1 result_type;
    typedef A0 r_type;
    NT2_FUNCTOR_CALL(2)
    {
      r_type r = a0*nt2::real(a1);
      r_type i = a0*nt2::imag(a1);
#ifndef BOOST_SIMD_NO_INVALIDS
      typename meta::as_logical<A1>::type is_real_a1 = is_real(a1);
      r = if_zero_else(logical_andnot(is_imag(a1), is_real_a1), r);
      i = if_zero_else(is_real_a1, i);
#endif
      return result_type(r, i);
    }
  };

  BOOST_DISPATCH_IMPLEMENT  ( multiplies_, tag::cpu_, (A0)(A1)
                            , ((generic_< complex_< arithmetic_<A0> > >))
                              ((generic_< arithmetic_<A1> >))
                            )
  {
    typedef A0 result_type;
    NT2_FUNCTOR_CALL(2)
    {
      return nt2::multiplies(a1, a0);
    }
  };
  BOOST_DISPATCH_IMPLEMENT  ( multiplies_, tag::cpu_, (A0)(A1)
                            , ((generic_< dry_ < arithmetic_<A0> > >))
                              ((generic_< complex_< arithmetic_<A1> > >))
                            )
  {
    typedef A1 result_type;
    NT2_FUNCTOR_CALL(2)
    {
      return nt2::multiplies(nt2::real(a0), a1);
    }
  };
  BOOST_DISPATCH_IMPLEMENT  ( multiplies_, tag::cpu_, (A0)(A1)
                            , ((generic_< complex_< arithmetic_<A0> > >))
                              ((generic_< dry_ < arithmetic_<A1> > >))
                            )
  {
    typedef A0 result_type;
    NT2_FUNCTOR_CALL(2)
    {
      return nt2::multiplies(a0, nt2::real(a1));
    }
  };

  // dry/dry
  BOOST_DISPATCH_IMPLEMENT  ( multiplies_, tag::cpu_, (A0)(A1)
                            , ((generic_< dry_< arithmetic_<A0> > >))
                              ((generic_< dry_< arithmetic_<A1> > >))
                            )
  {
    typedef typename nt2::meta::as_dry<A0>::type result_type;
    NT2_FUNCTOR_CALL(2)
    {
      return bitwise_cast<result_type>(nt2::real(a0)*nt2::real(a1));
    }
  };

} } }

#endif


text:
//  (C) Copyright John Maddock 2017.
//  Distributed under the Boost Software License, Version 1.0. (See
//  accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

#include <boost/integer/common_factor.hpp>

#if !defined(BOOST_NO_CXX11_NOEXCEPT) && !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)
//
// These tests don't pass with GCC-4.x:
//
#if !defined(BOOST_GCC) || (BOOST_GCC >= 50000)

void test_noexcept(unsigned char a, unsigned char b)
{
   static_assert(noexcept(boost::integer::gcd(static_cast<unsigned char>(a), static_cast<unsigned char>(b))), "Expected a noexcept function.");
#ifndef _MSC_VER
   // This generates an internal compiler error if enabled as well as the following test:
   static_assert(noexcept(boost::integer::gcd(static_cast<char>(a), static_cast<char>(b))), "Expected a noexcept function.");
#endif
   static_assert(noexcept(boost::integer::gcd(static_cast<signed char>(a), static_cast<signed char>(b))), "Expected a noexcept function.");
   static_assert(noexcept(boost::integer::gcd(static_cast<short>(a), static_cast<short>(b))), "Expected a noexcept function.");
   static_assert(noexcept(boost::integer::gcd(static_cast<unsigned short>(a), static_cast<unsigned short>(b))), "Expected a noexcept function.");
   static_assert(noexcept(boost::integer::gcd(static_cast<int>(a), static_cast<int>(b))), "Expected a noexcept function.");
   static_assert(noexcept(boost::integer::gcd(static_cast<unsigned int>(a), static_cast<unsigned int>(b))), "Expected a noexcept function.");
   static_assert(noexcept(boost::integer::gcd(static_cast<long>(a), static_cast<long>(b))), "Expected a noexcept function.");
   static_assert(noexcept(boost::integer::gcd(static_cast<unsigned long>(a), static_cast<unsigned long>(b))), "Expected a noexcept function.");
   static_assert(noexcept(boost::integer::gcd(static_cast<long long>(a), static_cast<long long>(b))), "Expected a noexcept function.");
   static_assert(noexcept(boost::integer::gcd(static_cast<unsigned long long>(a), static_cast<unsigned long long>(b))), "Expected a noexcept function.");
}

#endif
#endif


text: #include <boost/hana/fwd/fold.hpp>

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text:
/*
Author: Gudakov Ramil Sergeevich a.k.a. Gauss
Гудаков Рамиль Сергеевич
Contacts: [ramil2085@mail.ru, ramil2085@gmail.com]
See for more information LICENSE.md.
*/

#include <boost/asio/ip/impl/address_v4.ipp>
#include <string>
#include <iostream>
#include <stdio.h>
#include <thread>

#include "BL_Debug.h"
#include "CommonParam.h"
#include "NetTransport/MakerNetTransport.h"
#include "MMOEngine/include/Slave.h"
#include "MMOEngine/include/Master.h"
#include "MMOEngine/include/SuperServer.h"
#include "HiTimer.h"
#include "ResolverSelf_IP_v4.h"
#include "Logger.h"
#include "HandlerMMO_Slave.h"
#include "HandlerMMO_Master.h"
#include "HandlerMMO_SuperServer.h"
#include "ReversedContainerRise.h"
#include "InputCmdTestMMO_Server.h"
#include "ClusterMonitorServerHandler.h"
#include "SrcEvent_ex.h"

#define COUNT_SLAVE 3

void StartServer( int argc, char** argv );

int main( int argc, char** argv )
{
  setlocale( LC_ALL, "Russian" );

#ifdef WIN32
  std::string title = "Title Server ";
  for ( int i = 1; i < argc; i++ )
  {
    char s[1000];
    sprintf( s, "%s ", argv[i] );
    title += s;
  }
  system( title.data() );
#endif
#ifdef _DEBUG
  StartServer( argc, argv );
#else
  try
  {
    StartServer( argc, argv );
  }
  catch ( std::exception & e )
  {
    printf( "exception!!! %s\n", e.what() );
    getchar();
  }
#endif
  return 0;
}

void StartServer( int argc, char** argv )
{
  TInputCmdTestMMO_Server cmi;
  cmi.Init();
  cmi.SetArg( argc, argv );

  // обязательно инициализировать лог
  std::string sLocalHost;
  TResolverSelf_IP_v4 resolver;

  InitLogger( ServerLog );
  {
    int countIP_v4 = resolver.GetCount();
    GetLogger( ServerLog )->WriteF( "ip count = %d\n", countIP_v4 );
    for ( int i = 0; i < countIP_v4; i++ )
    {
      if ( resolver.Get( sLocalHost, i ) == false )
        continue;
      GetLogger( ServerLog )->WriteF( "ip = %s\n", sLocalHost.data() );
    }
  }

  if ( resolver.Get( sLocalHost, cmi.mInput.subnet ) )
    GetLogger( ServerLog )->WriteF( "use ip = %s\n", sLocalHost.data() );
  else
  {
    GetLogger( ServerLog )->WriteF( "FAIL subnet = %u\n", cmi.mInput.subnet );
    return;
  }

  std::vector<THandlerMMO_Slave*> arrHandlerSlave;

  TMakerNetTransport makerTransport;

  nsMMOEngine::TDescOpen descOpen;
  descOpen.subNet = cmi.mInput.subnet;
  typedef std::shared_ptr<nsMMOEngine::TSlave> TShared_Ptr_Slave;
  std::vector<TShared_Ptr_Slave> arrSlave;
  for ( int i = 0; i < COUNT_SLAVE; i++ )
  {
    TShared_Ptr_Slave pSlave = TShared_Ptr_Slave( new nsMMOEngine::TSlave );
    THandlerMMO_Slave* pHandlerSlave = new THandlerMMO_Slave( pSlave.get() );
    pSlave->Init( &makerTransport );
    descOpen.port = SLAVE_PORT + i;
    pSlave->Open( &descOpen );
    pSlave->SetLoad( 0 );// всегда в начале нет нагрузки
    pSlave->SetDstObject( pHandlerSlave );
    pSlave->SetSelfID( descOpen.port );
    arrSlave.push_back( pSlave );
    arrHandlerSlave.push_back( pHandlerSlave );
  }

  std::shared_ptr<nsMMOEngine::TMaster>      pMaster( new nsMMOEngine::TMaster );
  std::shared_ptr<nsMMOEngine::TSuperServer> pSuperServer( new nsMMOEngine::TSuperServer );
  std::shared_ptr<THandlerMMO>               handlerMaster( new THandlerMMO_Master( pMaster.get() ) );
  std::shared_ptr<THandlerMMO>               handlerSuperServer( new THandlerMMO_SuperServer( pSuperServer.get() ) );

  TClusterMonitorServerHandler cmsTransport( cmi.mInput.subnet, pMaster.get() );

  descOpen.port = MASTER_PORT;
  pMaster->Init( &makerTransport );
  pMaster->Open( &descOpen );
  pMaster->SetDstObject( handlerMaster.get() );
  pMaster->SetSelfID( descOpen.port );

  descOpen.port = SUPER_SERVER_PORT;
  pSuperServer->Init( &makerTransport );
  pSuperServer->Open( &descOpen );
  pSuperServer->SetDstObject( handlerSuperServer.get() );
  pSuperServer->SetSelfID( descOpen.port );

  // сначала мастер цепляется к суперсерверу,
  // потом slave-ы
  TIP_Port ssIP_Port;
  ssIP_Port.ip = boost::asio::ip::address_v4::from_string( sLocalHost ).to_ulong();
  ssIP_Port.port = SUPER_SERVER_PORT;
  std::string login = MASTER_LOGIN;
  std::string password = MASTER_PASSWORD;
  pMaster->ConnectUp( ssIP_Port, login, password, cmi.mInput.subnet );
  TIP_Port masterIP_Port;
  masterIP_Port.ip = boost::asio::ip::address_v4::from_string( sLocalHost ).to_ulong();
  masterIP_Port.port = MASTER_PORT;
  password = SLAVE_PASSWORD;
  for ( int i = 0; i < COUNT_SLAVE; i++ )
  {
    char sLogin[100];
    sprintf( sLogin, "%d", i );
    login = SLAVE_LOGIN;// sLogin;
    arrSlave[i]->ConnectUp( masterIP_Port, login, password, cmi.mInput.subnet );
  }

  const unsigned int printInterval = 6000;
  auto printTime = ht_GetMSCount() + printInterval;

  unsigned int start = 0;
  unsigned int limitDeltaTime = 6000;// ms
  int iCycle = 0;

  while ( true )
  {
    auto now = ht_GetMSCount();

    if ( iCycle == 0 )// начало расчета скорости работы
      start = now;

    if ( printTime < now )
    {
      THandlerMMO::PrintCC( ServerLog );
      printTime = now + printInterval;
    }

    // Work - реакции мастера и суперсервера
    pSuperServer->Work();
    pMaster->Work();
    for ( auto pSlave : arrSlave )
      pSlave->Work();
    // Handle
    handlerMaster->Work();
    handlerSuperServer->Work();
    for ( auto pHandlerSlave : arrHandlerSlave )
      pHandlerSlave->Work();

    cmsTransport.Work();

    iCycle++;
    auto delta = ht_GetMSCount() - start;
    if ( delta >= limitDeltaTime )
    {
      auto speed_ms = delta * 1.0f / iCycle;
      GetLogger( ServerLog )->WriteF( "time of cycle = %f ms\n", speed_ms );
      iCycle = 0;
    }
  }
}
//-----------------------------------------------------------------------

max_stars_repo_name: RamilGauss/MMO-Framework

max_issues_repo_name: RamilGauss/MMO-Framework

max_forks_repo_name: RamilGauss/MMO-Framework


text:
#pragma once

#include <boost/asio.hpp>
#include <boost/signals2.hpp>
#include <beluga/event.hpp>
#include <beluga/buffer.hpp>
#include <memory>

namespace beluga
{
    class tcp_client : public std::enable_shared_from_this<tcp_client>
    {
    public:
	class connect_event : public continue_event
	{
	public:
	    connect_event(bool _continue, const boost::asio::ip::tcp::endpoint& endpoint);

	    const boost::asio::ip::tcp::endpoint& get_endpoint() const;

	private:
	    boost::asio::ip::tcp::endpoint endpoint;
	};

	using connect_error_event = error_event;

	class receive_event : public continue_event
	{
	public:
	    receive_event(bool _continue, const beluga::dynamic_buffer& buffer);

	    void set_buffer(const beluga::dynamic_buffer& buffer);
	    beluga::dynamic_buffer& get_buffer();
	    const beluga::dynamic_buffer& get_buffer() const;

	private:
	    beluga::dynamic_buffer buffer;
	};

	using receive_error_event = error_event;

	using on_receive_error_type = boost::signals2::signal<void(receive_error_event& event)>;
	using on_receive_type = boost::signals2::signal<void(receive_event& event)>;

	using on_connect_error_type = boost::signals2::signal<void(connect_error_event& event)>;
	using on_connect_type = boost::signals2::signal<void(connect_event& event)>;

	tcp_client(const tcp_client&) = delete;
	tcp_client& operator=(const tcp_client&) = delete;

	virtual ~tcp_client() = default;

	boost::asio::ip::tcp::socket& get_socket();
	const boost::asio::ip::tcp::socket& get_socket() const;

	template <typename... args>
	static std::shared_ptr<tcp_client> create(args&&... params);

	void connect(const boost::asio::ip::tcp::endpoint& endpoint);

	void receive();

	on_receive_error_type on_receive_error;
	on_receive_type on_receive;

	on_connect_error_type on_connect_error;
	on_connect_type on_connect;

    protected:
	tcp_client(boost::asio::ip::tcp::socket& socket);
	tcp_client(boost::asio::io_service& io_service);

    private:
	boost::asio::ip::tcp::socket socket;
    };
}

#include <beluga/tcp/tcp_client.inl>

max_stars_repo_name: Stazer/beluga

max_issues_repo_name: Stazer/beluga

max_forks_repo_name: Stazer/beluga


text:
// Boost.Units - A C++ library for zero-overhead dimensional analysis and
// unit/quantity manipulation and conversion
//
// Copyright (C) 2003-2008 Matthias Christian Schabel
// Copyright (C) 2007-2008 Steven Watanabe
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

#ifndef BOOST_UNITS_ANGLE_GRADIAN_BASE_UNIT_HPP
#define BOOST_UNITS_ANGLE_GRADIAN_BASE_UNIT_HPP

#include <boost/units/conversion.hpp>
#include <boost/units/base_units/angle/radian.hpp>

BOOST_UNITS_DEFINE_BASE_UNIT_WITH_CONVERSIONS(angle,gradian,"gradian","grad",6.28318530718/400.,boost::units::angle::radian_base_unit,-102);

#if BOOST_UNITS_HAS_BOOST_TYPEOF

#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()

BOOST_TYPEOF_REGISTER_TYPE(boost::units::angle::gradian_base_unit)

#endif

#endif // BOOST_UNITS_ANGLE_GRADIAN_BASE_UNIT_HPP

max_stars_repo_name: rudylee/expo

max_issues_repo_name: rudylee/expo

max_forks_repo_name: rudylee/expo


text: #include <boost/smart_ptr/intrusive_ref_counter.hpp>


text:
#ifndef ASLAM_BACKEND_HOMOGENEOUS_EXPRESSION_NODE_HPP
#define ASLAM_BACKEND_HOMOGENEOUS_EXPRESSION_NODE_HPP

#include <aslam/backend/JacobianContainer.hpp>
#include "TransformationExpressionNode.hpp"
#include <boost/shared_ptr.hpp>
#include <eigen3/Eigen/Core>
#include "EuclideanExpression.hpp"

namespace aslam {
  namespace backend {
    class TransformationExpressionNode;

    /**
     * \class HomogeneousExpressionNode
     * \brief The superclass of all classes representing homogeneous points.
     */
    class HomogeneousExpressionNode
    {
    public:
      EIGEN_MAKE_ALIGNED_OPERATOR_NEW

      HomogeneousExpressionNode();
      virtual ~HomogeneousExpressionNode();

      /// \brief Evaluate the homogeneous matrix.
      Eigen::Vector4d toHomogeneous() const;

      /// \brief Evaluate the Jacobians
      void evaluateJacobians(JacobianContainer & outJacobians) const;

      /// \brief Evaluate the Jacobians and apply the chain rule.
      void evaluateJacobians(JacobianContainer & outJacobians, const Eigen::MatrixXd & applyChainRule) const;
      virtual void getDesignVariables(DesignVariable::set_t & designVariables) const;
    protected:
      // These functions must be implemented by child classes.
      virtual Eigen::Vector4d toHomogeneousImplementation() const = 0;
      virtual void evaluateJacobiansImplementation(JacobianContainer & outJacobians) const = 0;
      virtual void evaluateJacobiansImplementation(JacobianContainer & outJacobians, const Eigen::MatrixXd & applyChainRule) const = 0;
      virtual void getDesignVariablesImplementation(DesignVariable::set_t & designVariables) const = 0;

    };

    /**
     * \class HomogeneousExpressionNodeMultiply
     *
     * \brief A class representing the transformation of a homogeneous point
     *
     */
    class HomogeneousExpressionNodeMultiply : public HomogeneousExpressionNode
    {
    public:
      EIGEN_MAKE_ALIGNED_OPERATOR_NEW

      HomogeneousExpressionNodeMultiply(boost::shared_ptr<TransformationExpressionNode> lhs,
				     boost::shared_ptr<HomogeneousExpressionNode> rhs);
      virtual ~HomogeneousExpressionNodeMultiply();

    private:
      virtual Eigen::Vector4d toHomogeneousImplementation() const;
      virtual void evaluateJacobiansImplementation(JacobianContainer & outJacobians) const;
      virtual void evaluateJacobiansImplementation(JacobianContainer & outJacobians, const Eigen::MatrixXd & applyChainRule) const;
      virtual void getDesignVariablesImplementation(DesignVariable::set_t & designVariables) const;

      boost::shared_ptr<TransformationExpressionNode> _lhs;
      mutable Eigen::Matrix4d _T_lhs;
      boost::shared_ptr<HomogeneousExpressionNode> _rhs;
      mutable Eigen::Vector4d _p_rhs;
    };

    class HomogeneousExpressionNodeConstant : public HomogeneousExpressionNode
    {
    public:
      EIGEN_MAKE_ALIGNED_OPERATOR_NEW

      HomogeneousExpressionNodeConstant(const Eigen::Vector4d & p);
      virtual ~HomogeneousExpressionNodeConstant();

        void set(const Eigen::Vector4d & p){ _p = p; }
    private:
      virtual Eigen::Vector4d toHomogeneousImplementation() const;
      virtual void evaluateJacobiansImplementation(JacobianContainer & outJacobians) const;
      virtual void evaluateJacobiansImplementation(JacobianContainer & outJacobians, const Eigen::MatrixXd & applyChainRule) const;
      virtual void getDesignVariablesImplementation(DesignVariable::set_t & designVariables) const;

      Eigen::Vector4d _p;
    };

  class HomogeneousExpressionNodeEuclidean : public HomogeneousExpressionNode
    {
    public:
      EIGEN_MAKE_ALIGNED_OPERATOR_NEW

      HomogeneousExpressionNodeEuclidean( boost::shared_ptr<EuclideanExpressionNode> p);
      virtual ~HomogeneousExpressionNodeEuclidean();

    private:
      virtual Eigen::Vector4d toHomogeneousImplementation() const;
      virtual void evaluateJacobiansImplementation(JacobianContainer & outJacobians) const;
      virtual void evaluateJacobiansImplementation(JacobianContainer & outJacobians, const Eigen::MatrixXd & applyChainRule) const;
      virtual void getDesignVariablesImplementation(DesignVariable::set_t & designVariables) const;

      boost::shared_ptr<EuclideanExpressionNode> _p;
    };

  } // namespace backend
} // namespace aslam

#endif /* ASLAM_BACKEND_HOMOGENEOUS_EXPRESSION_NODE_HPP */

max_stars_repo_name: mmmspatz/kalibr

max_issues_repo_name: mmmspatz/kalibr

max_forks_repo_name: mmmspatz/kalibr


text:
/*
 * Copyright (c) 2013 Aldebaran Robotics. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the COPYING file.
 */

#include <utility>
#include <boost/program_options.hpp>
#include <boost/range/adaptor/transformed.hpp>
#include <qi/trackable.hpp>
#include <qi/applicationsession.hpp>
#include <qi/anyvalue.hpp>
#include <qi/log.hpp>
#include "applicationsession_internal.hpp"

qiLogCategory("qi.applicationsession");

namespace qi
{

namespace
{

using appsession_internal::ProgramOptions;
boost::synchronized_value<boost::optional<ProgramOptions>> g_defaultProgramOptions;

template<typename... Args>
ProgramOptions emplaceDefaultProgramOptions(Args&&... args)
{
  auto syncProgOpts = g_defaultProgramOptions.synchronize();
  syncProgOpts->emplace(std::forward<Args>(args)...);
  return syncProgOpts->get();
}

/// @throws `boost::bad_optional_access` if `setDefaultProgramOptions` was not called before.
ProgramOptions defaultProgramOptions()
{
  return g_defaultProgramOptions->value();
}

void onDisconnected(const std::string& /*errorMessage*/)
{
  Application::stop();
}

// This function is used to add the callback before the call of Application's constructor
int& addParseOptions(int& argc)
{
  Application::atEnter([]{
    const auto programOptions = emplaceDefaultProgramOptions(Application::arguments());
    Application::setArguments(programOptions.unrecognizedArgs);
    Application::options().add(ProgramOptions::description());
  });
  return argc;
}

}

class ApplicationSessionPrivate : public Trackable<ApplicationSessionPrivate>
{
public:
  ApplicationSessionPrivate(const ApplicationSession::Config& config)
    : _config(reconfigureWithProgramOptions(config, defaultProgramOptions()))
    , _session(makeSession(_config.sessionConfig()))
    , _init(false)
  {
    if (!(_config.option() & ApplicationSession::Option_NoAutoExit))
    {
      _session->disconnected.connect(&onDisconnected);
    }
  }

  virtual ~ApplicationSessionPrivate()
  {
    destroy();
    Application::stop();
    _session->close();
  }

  void start()
  {
    // Rely on the configuration we passed to the session for the URLs.

    if (_config.standalone())
    {
      _session->listenStandalone();
      return;
    }

    _session->connect();

    // Only listen if there were listen URLs specified on the command line.
    if (defaultProgramOptions().hasCliListenUrl)
      _session->listen();
  }

public:
  const ApplicationSession::Config _config;
  SessionPtr _session;
  bool _init;
  boost::mutex _mutex;
};

enum StateMachineConfig
{
  StateMachineConfig_unset = 0,
  StateMachineConfig_standAlone = 1,
  StateMachineConfig_connect = 2,
};

ApplicationSession::Config::Config()
  : _standalone(false)
  , _opt(Option_None)
{
}

ApplicationSession::Config::~Config()
{
}

ApplicationSession::Config& ApplicationSession::Config::setDefaultStandAlone(bool standalone)
{
  return setStandalone(standalone);
}

bool ApplicationSession::Config::defaultStandAlone() const
{
  return standalone();
}

ApplicationSession::Config& ApplicationSession::Config::setStandalone(bool standalone)
{
  _standalone = standalone;
  return *this;
}

bool ApplicationSession::Config::standalone() const
{
  return _standalone;
}

ApplicationSession::Config& ApplicationSession::Config::setOption(ApplicationSession::Option opt)
{
  _opt = opt;
  return *this;
}
ApplicationSession::Option ApplicationSession::Config::option() const
{
  return _opt;
}

ApplicationSession::Config& ApplicationSession::Config::setDefaultUrl(const Url& url)
{
  return setConnectUrl(url);
}

const Url& ApplicationSession::Config::defaultUrl() const
{
  return connectUrl().value();
}

ApplicationSession::Config& ApplicationSession::Config::setConnectUrl(Url url)
{
  _sessionConfig.connectUrl = std::move(url);
  return *this;
}

const boost::optional<Url>& ApplicationSession::Config::connectUrl() const
{
  return _sessionConfig.connectUrl;
}

ApplicationSession::Config& ApplicationSession::Config::setDefaultListenUrl(const Url& listenUrl)
{
  setListenUrls({ listenUrl });
  return *this;
}

const Url& ApplicationSession::Config::defaultListenUrl() const
{
  return listenUrls().front();
}

ApplicationSession::Config& ApplicationSession::Config::addListenUrl(Url listenUrl)
{
  _sessionConfig.listenUrls.push_back(std::move(listenUrl));
  return *this;
}

ApplicationSession::Config& ApplicationSession::Config::setListenUrls(std::vector<Url> listenUrls)
{
  _sessionConfig.listenUrls = std::move(listenUrls);
  return *this;
}

const std::vector<Url>&ApplicationSession::Config::listenUrls() const
{
  return _sessionConfig.listenUrls;
}

ApplicationSession::Config& ApplicationSession::Config::setSessionConfig(
  SessionConfig sessConfig)
{
  _sessionConfig = std::move(sessConfig);
  return *this;
}

const SessionConfig& ApplicationSession::Config::sessionConfig() const
{
  return _sessionConfig;
}

ApplicationSession::Config& ApplicationSession::Config::setName(const std::string& name)
{
  _name = name;
  return *this;
}
const std::string& ApplicationSession::Config::name() const
{
  return _name;
}

ApplicationSession::ApplicationSession(int& argc, char**& argv, int opt, const Url& defaultUrl)
  : Application(addParseOptions(argc), argv)
  , _p(new ApplicationSessionPrivate(
      Config{}.setConnectUrl(defaultUrl).setOption(static_cast<Option>(opt))))
{
}

ApplicationSession::ApplicationSession(const std::string& name,
                                       int& argc,
                                       char**& argv,
                                       int opt,
                                       const Url& defaultUrl)
  : Application(addParseOptions(argc), argv, name)
  , _p(new ApplicationSessionPrivate(
      Config{}.setName(name).setConnectUrl(defaultUrl).setOption(static_cast<Option>(opt))))
{
}

ApplicationSession::ApplicationSession(int& argc, char**& argv, const Config& defaultConfig)
  : Application(addParseOptions(argc), argv, defaultConfig.name())
  , _p(new ApplicationSessionPrivate(defaultConfig))
{
}

ApplicationSession::~ApplicationSession() = default;

SessionPtr ApplicationSession::session() const
{
  return _p->_session;
}

const ApplicationSession::Config& ApplicationSession::config() const
{
  return _p->_config;
}

Url ApplicationSession::url() const
{
  const auto connectUrl = _p->_config.connectUrl();
  // The configuration must hold a connect URL as it is guaranteed by `finalizeConfig`.
  QI_ASSERT_TRUE(connectUrl.is_initialized());
  return *_p->_config.connectUrl();
}

Url ApplicationSession::listenUrl() const
{
  const auto& confListenUrls = _p->_config.sessionConfig().listenUrls;
  QI_ASSERT_FALSE(confListenUrls.empty());
  return confListenUrls.at(0);
}

std::vector<Url> ApplicationSession::allListenUrl() const
{
  return _p->_config.sessionConfig().listenUrls;
}

void ApplicationSession::start()
{
  startSession();
}

void ApplicationSession::startSession()
{
  {
    boost::mutex::scoped_lock lock(_p->_mutex);

    if (_p->_init)
    {
      return;
    }
    _p->_init = true;
  }

  // The connection is asynchronous, therefore a wait is expected here
  _p->start();
}

void ApplicationSession::run()
{
  if(!_p->_session->isConnected())
    startSession();
  Application::run();
}

bool ApplicationSession::standAlone()
{
  return _p->_config.standalone();
}

std::string ApplicationSession::helpText() const
{
  return Application::helpText();
}

}

max_stars_repo_name: arntanguy/libqi

max_issues_repo_name: arntanguy/libqi

max_forks_repo_name: arntanguy/libqi