<commit_before>/// @file
/// @author uentity
/// @date 24.08.2016
/// @brief Plugins subsystem of BS kernel
/// @copyright
/// This Source Code Form is subject to the terms of the Mozilla Public License,
/// v. 2.0. If a copy of the MPL was not distributed with this file,
/// You can obtain one at https://mozilla.org/MPL/2.0/

#pragma once

#include <bs/kernel.h>
#include <bs/detail/lib_descriptor.h>
#include <boost/pool/pool_alloc.hpp>
#include <map>

namespace blue_sky { namespace detail {
/*-----------------------------------------------------------------------------
 *  helper wrapper for storing objects in kernel dictionary
 *  designed to have specific valid nill element
 *-----------------------------------------------------------------------------*/
template< class T >
struct elem_ptr {
	typedef T elem_t;
	// nil ctor
	elem_ptr() : p_(&nil_el()) {}

	elem_ptr(const T& el) : p_(&el) {}

	elem_ptr (const T* el) : p_(el ? el : &nil_el()) {}

	elem_ptr& operator =(const T& el) {
		p_ = &el;
		return *this;
	}
	elem_ptr& operator =(const T* el) {
		p_ = el ? el : &nil_el();
		return *this;
	}

	const T* operator ->() const { return p_; }

	// conversion to elem_t
	const T* get() const { return p_; }
	const T& elem() const { return *p_; }
	const T& operator *() const { return *p_; }

	bool is_nil() const {
		return p_->is_nil();
	}

	operator bool() const {
		return !is_nil();
	}

	static const T& nil_el() {
		// here we rely on gact that if elem_ptr has external linkage (it should)
		// then there's only one copy on nil_obj that will be shared
		// among all translation units
		static const T nil_obj;
		return nil_obj;
	}

private:
	const T* p_;
};
// alias
using pd_ptr = elem_ptr< plugin_descriptor >;
using td_ptr = elem_ptr< type_descriptor >;

/*-----------------------------------------------------------------------------
 *  main type factory element
 *  contains pair of plugin_descriptor and type_descriptor wrapped by elem_ptr
 *-----------------------------------------------------------------------------*/
//typedef type_tuple fab_elem;
struct fab_elem {
	// nil ctor
	fab_elem() {}

	fab_elem(const pd_ptr& pd, const type_descriptor& td)
		: pd_(pd), td_(td)
	{}

	fab_elem(const type_descriptor& td)
		: td_(td)
	{}

	fab_elem(const plugin_descriptor& pd)
		: pd_(pd)
	{}

	fab_elem(const type_tuple& tt)
		: pd_(tt.pd), td_(tt.td)
	{}

	fab_elem(const pd_ptr& pd)
		: pd_(pd)
	{}
	fab_elem(const td_ptr& td)
		: td_(td)
	{}

	bool is_nil() const {
		return (td_.is_nil() && pd_.is_nil());
	}

	operator bool() const {
		return !is_nil();
	}

	operator type_tuple() const {
		return type_tuple(*pd_, *td_);
	};

	pd_ptr pd_;
	td_ptr td_;
};
// alias
using fe_ptr = elem_ptr< fab_elem >;

// pd_ptrs comparison by name
struct pdp_comp_name {
	bool operator()(const pd_ptr& lhs, const pd_ptr& rhs) const {
		return lhs->name < rhs->name;
	}
};

// fab_elem sorting order by bs_type_info
struct fe_comp_ti {
	bool operator()(const fab_elem& lhs, const fab_elem& rhs) const {
		return lhs.td_ < rhs.td_;
	}
};

// fab element comparison by string typename
struct fe_comp_typename {
	bool operator()(const fab_elem& lhs, const fab_elem& rhs) const {
		return lhs.td_->type_name() < rhs.td_->type_name();
	}
};

// fab elements comparison by plugin name
struct fe_comp_pd {
	bool operator()(const fab_elem& lhs, const fab_elem& rhs) const {
		return (lhs.pd_->name < rhs.pd_->name);
	}
};

/*-----------------------------------------------------------------
 * Kernel plugins loading subsystem definition
 *----------------------------------------------------------------*/
struct BS_HIDDEN_API kernel_plugins_subsyst {

	const plugin_descriptor kernel_pd_;       //! plugin descriptor for kernel types
	const plugin_descriptor runtime_pd_;      //! plugin descriptor for runtime types

	//! plugin_descriptor -> lib_descriptor 1-to-1 relation
	using plugins_enum_t = std::map<
		pd_ptr, lib_descriptor, pdp_comp_name,
		boost::fast_pool_allocator<<commit_msg>kernel.plugins_subsyst: fix fatal error with using wrong comparator for types in factory<commit_after>/// @file
/// @author uentity
/// @date 24.08.2016
/// @brief Plugins subsystem of BS kernel
/// @copyright
/// This Source Code Form is subject to the terms of the Mozilla Public License,
/// v. 2.0. If a copy of the MPL was not distributed with this file,
/// You can obtain one at https://mozilla.org/MPL/2.0/

#pragma once

#include <bs/kernel.h>
#include <bs/detail/lib_descriptor.h>
#include <boost/pool/pool_alloc.hpp>
#include <map>

namespace blue_sky { namespace detail {
/*-----------------------------------------------------------------------------
 *  helper wrapper for storing objects in kernel dictionary
 *  designed to have specific valid nill element
 *-----------------------------------------------------------------------------*/
template< class T >
struct elem_ptr {
	typedef T elem_t;
	// nil ctor
	elem_ptr() : p_(&nil_el()) {}

	elem_ptr(const T& el) : p_(&el) {}

	elem_ptr (const T* el) : p_(el ? el : &nil_el()) {}

	elem_ptr& operator =(const T& el) {
		p_ = &el;
		return *this;
	}
	elem_ptr& operator =(const T* el) {
		p_ = el ? el : &nil_el();
		return *this;
	}

	const T* operator ->() const { return p_; }

	// conversion to elem_t
	const T* get() const { return p_; }
	const T& elem() const { return *p_; }
	const T& operator *() const { return *p_; }

	bool is_nil() const {
		return p_->is_nil();
	}

	operator bool() const {
		return !is_nil();
	}

	static const T& nil_el() {
		// here we rely on gact that if elem_ptr has external linkage (it should)
		// then there's only one copy on nil_obj that will be shared
		// among all translation units
		static const T nil_obj;
		return nil_obj;
	}

private:
	const T* p_;
};
// alias
using pd_ptr = elem_ptr< plugin_descriptor >;
using td_ptr = elem_ptr< type_descriptor >;

/*-----------------------------------------------------------------------------
 *  main type factory element
 *  contains pair of plugin_descriptor and type_descriptor wrapped by elem_ptr
 *-----------------------------------------------------------------------------*/
//typedef type_tuple fab_elem;
struct fab_elem {
	// nil ctor
	fab_elem() {}

	fab_elem(const pd_ptr& pd, const type_descriptor& td)
		: pd_(pd), td_(td)
	{}

	fab_elem(const type_descriptor& td)
		: td_(td)
	{}

	fab_elem(const plugin_descriptor& pd)
		: pd_(pd)
	{}

	fab_elem(const type_tuple& tt)
		: pd_(tt.pd), td_(tt.td)
	{}

	fab_elem(const pd_ptr& pd)
		: pd_(pd)
	{}
	fab_elem(const td_ptr& td)
		: td_(td)
	{}

	bool is_nil() const {
		return (td_.is_nil() && pd_.is_nil());
	}

	operator bool() const {
		return !is_nil();
	}

	operator type_tuple() const {
		return type_tuple(*pd_, *td_);
	};

	pd_ptr pd_;
	td_ptr td_;
};
// alias
using fe_ptr = elem_ptr< fab_elem >;

// pd_ptrs comparison by name
struct pdp_comp_name {
	bool operator()(const pd_ptr& lhs, const pd_ptr& rhs) const {
		return lhs->name < rhs->name;
	}
};

// fab_elem sorting order by bs_type_info
struct fe_comp_ti {
	bool operator()(const fab_elem& lhs, const fab_elem& rhs) const {
		return *lhs.td_ < *rhs.td_;
	}
};

// fab element comparison by string typename
struct fe_comp_typename {
	bool operator()(const fab_elem& lhs, const fab_elem& rhs) const {
		return lhs.td_->type_name() < rhs.td_->type_name();
	}
};

// fab elements comparison by plugin name
struct fe_comp_pd {
	bool operator()(const fab_elem& lhs, const fab_elem& rhs) const {
		return (lhs.pd_->name < rhs.pd_->name);
	}
};

/*-----------------------------------------------------------------
 * Kernel plugins loading subsystem definition
 *----------------------------------------------------------------*/
struct BS_HIDDEN_API kernel_plugins_subsyst {

	const plugin_descriptor kernel_pd_;       //! plugin descriptor for kernel types
	const plugin_descriptor runtime_pd_;      //! plugin descriptor for runtime types

	//! plugin_descriptor -> lib_descriptor 1-to-1 relation
	using plugins_enum_t = std::map<
		pd_ptr, lib_descriptor, pdp_comp_name,
		boost::fast_pool_allocator<
{'fraction_non_alphanumeric': 0.2227998514667657, 'fraction_numerical': 0.0034657754672607994, 'mean_word_length': 2.321002877106453, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 37, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4422116', 'n_tokens_mistral': 2685, 'n_tokens_neox': 2544, 'n_words': 792}