В этом разделе мы предоставим «рецепт» для добавления новой специальной функции в эту библиотеку, чтобы облегчить жизнь будущим авторам, желающим внести свой вклад. Мы предположим, что функция возвращает один результат с плавающей точкой и принимает два аргумента с плавающей точкой. Для изложения мы дадим функции имя<my_special>.
Обычно реализация такой функции разбивается на два слоя — общедоступный пользовательский слой и внутренний уровень реализации, выполняющий фактическую работу. Слой реализации объявляется внутри пространства имен<detail>и имеет простую подпись:
namespace boost { namespace math { namespace detail {
template <class T, class Policy>
T my_special_imp(const T& a, const T&b, const Policy& pol)
{
   
}
}}} 
Мы вернемся к тому, что может войти в реализацию позже, но сначала давайте посмотрим на пользовательский уровень. Это состоит из двух перегрузок функции, с аргументомПолитикаи без него:
namespace boost{ namespace math{
template <class T, class U>
typename tools::promote_args<T, U>::type my_special(const T& a, const U& b);
template <class T, class U, class Policy>
typename tools::promote_args<T, U>::type my_special(const T& a, const U& b, const Policy& pol);
}} 
Обратите внимание, что каждый аргумент имеет различный тип шаблона - это позволяет использовать аргументы смешанного типа - тип возврата вычисляется из класса признаков и является «общим типом» всех аргументов после того, как любые целочисленные аргументы были продвинуты на тип<double>.
Осуществление неполитической перегрузки тривиально:
namespace boost{ namespace math{
template <class T, class U>
inline typename tools::promote_args<T, U>::type my_special(const T& a, const U& b)
{
   
   return my_special(a, b, policies::policy<>();
}
}} 
Реализация другой перегрузки несколько сложнее, так как есть некоторое метапрограммирование, но с точки зрения времени выполнения все еще является функцией пересылки одной строки. Вот комментарии, объясняющие, что делает каждая строка:
namespace boost{ namespace math{
template <class T, class U, class Policy>
inline typename tools::promote_args<T, U>::type my_special(const T& a, const U& b, const Policy& pol)
{
   
   
   
   
   
   BOOST_FPU_EXCEPTION_GUARD
   
   
   
   
   typedef typename tools::promote_args<T, U>::type result_type;
   
   
   
   
   typedef typename policies::evaluation<result_type, Policy>::type value_type;
   
   
   
   
   
   
   
   
   
   
   typedef typename policies::normalise<
      Policy,
      policies::promote_float<false>,
      policies::promote_double<false>,
      policies::discrete_quantile<>,
      policies::assert_undefined<> >::type forwarding_policy;
   
   
   
   
   
   
   return policies::checked_narrowing_cast<result_type, forwarding_policy>(
         detail::my_special_imp(
               static_cast<value_type>(a),
               static_cast<value_type>(x),
               forwarding_policy()),
         "boost::math::my_special<%1%>(%1%, %1%)");
}
}} 
Сейчас мы почти на месте, нам просто нужно прояснить детали уровня реализации:
namespace boost { namespace math { namespace detail {
template <class T, class Policy>
T my_special_imp(const T& a, const T&b, const Policy& pol)
{
   
}
}}} 
Следующие руководящие принципы указывают, что (кроме базовой арифметики) может пойти в реализации:
- Условия ошибки (например, плохие аргументы) должны обрабатываться путем вызова одного изобработчиков ошибок на основе политики..
 
- Звонки в стандартные библиотечные функции должны быть сделаны неквалифицированными (это позволяет зависимому от аргумента поиску найти стандартные библиотечные функции для определяемых пользователем типов плавающих точек, таких как те изBoost.Multiprecision). Кроме того, макрос<
BOOST_MATH_STD_USING>должен появиться в начале функции (заметьте, что после этого нет полуколона!), так что все математические функции в<namespace
           std>видны в текущем объеме. 
- Звонки на другие специальные функции должны выполняться в качестве полностью квалифицированных вызовов и включать в качестве последнего аргумента политический параметр, например<
boost::math::tgamma(a,pol)>. 
- Там, где это возможно, для оценки последовательностей, непрерывных фракций, полиномов или нахождения корней следует использовать одну из функцийкотельной пластины. В любом случае, после любого итеративного метода следует проверить, что количество итераций не превысило максимум, указанный вПолитикетипа, и если оно действительно закончилось в результате превышения максимума, то следует вызвать соответствующего обработчика ошибок (см. существующий код для примеров).
 
- Численные константы, такие как π и т.д., должны быть получены посредством вызовасоответствующей функции, например:<
constants::pi<T>()>. 
- Там, где используются таблицы коэффициентов (например, для рациональных приближений), следует позаботиться о том, чтобы они были инициализированы при запуске программы для обеспечения безопасности потока при использовании определенных пользователем типов чисел. См., например, использование<
erf_initializer>вerf.hpp. 
 
Вот некоторые другие полезные внутренние функции: