ccgsl 2.7.2
C++wrappersforGnuScientificLibrary
function_scl.hpp
Go to the documentation of this file.
1/*
2 * $Id: function_scl.hpp 289 2012-12-04 15:32:17Z jdl3 $
3 * Copyright (C) 2010, 2011, 2012, 2019, 2020 John D Lamb
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or (at
8 * your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#ifndef CCGSL_FUNCTION_SCL_HPP
21#define CCGSL_FUNCTION_SCL_HPP
22
23// For std::pair
24#include<utility>
25// For std::swap
26#if __cplusplus <= 199711L
27#include<algorithm>
28#endif
29
30#include<gsl/gsl_math.h>
31
32namespace gsl {
96 class function_scl : public gsl_function {
97#ifndef DOXYGEN_SKIP
98 private:
102 struct base_F {
106 typedef double (*function_t)(double,void*);
110 virtual ~base_F(){};
115 virtual function_t function() = 0;
116 };
120 template<typename A>
121 class Fx : public base_F {
122 public:
127 Fx( double (*const f)(A) ) : f( f ){}
131 function_t function(){ return &fn; }
132 private:
136 double (*const f)(A);
137 public:
144 static double fn( double x, void* params ){
145 return reinterpret_cast<Fx<A>*>( params )->f( x ); }
146 };
150 template<typename A>
151 class Fxc : public base_F {
152 public:
157 Fxc( double const (*const f)(A) ) : f( f ){}
161 function_t function(){ return &fn; }
162 private:
166 double const (*const f)(A);
167 public:
174 static double fn( double x, void* params ){
175 return reinterpret_cast<Fxc<A>*>( params )->f( x ); }
176 };
181 template<typename T, typename R, typename A>
182 class F : public base_F {
183 public:
191 F(T& c, R (T::*f)(A)) : c( c ), f(f) {}
197 double operator()( double x ){ return (c.*f)( x ); }
201 function_t function(){ return &function_s; }
202 private:
211 static double function_s( double x, void* params ){
212 F<T,R,A>* const cl = reinterpret_cast<F<T,R,A>*>( params );
213 return (cl->c.*cl->f)(x); }
217 T& c;
221 R (T::*f)(A);
222 };
227 template<typename T, typename R, typename A>
228 class Fc : public base_F {
229 public:
237 Fc(T& c, R (T::*f)(A) const) : c( c ), f(f) {}
243 double operator()( double x ){ return (c.*f)( x ); }
247 function_t function(){ return &function_s; }
248 private:
257 static double function_s( double x, void* params ){
258 Fc<T,R,A>* const cl = reinterpret_cast<Fc<T,R,A>*>( params );
259 return (cl->c.*cl->f)(x); }
263 T& c;
267 R (T::*f)(A) const;
268 };
272 template<typename T, typename R, typename A>
273 class Fv : public base_F {
274 public:
282 Fv(T& c, R (T::*f)(A) volatile) : c( c ), f(f) {}
288 double operator()( double x ){ return (c.*f)( x ); }
292 function_t function(){ return &function_s; }
293 private:
302 static double function_s( double x, void* params ){
303 Fv<T,R,A>* const cl = reinterpret_cast<Fv<T,R,A>*>( params );
304 return (cl->c.*cl->f)(x); }
308 T& c;
312 R (T::*f)(A) volatile;
313 };
317 template<typename T, typename R, typename A>
318 class Fcv : public base_F {
319 public:
327 Fcv(T& c, R (T::*f)(A) const volatile) : c( c ), f(f) {}
333 double operator()( double x ){ return (c.*f)( x ); }
337 function_t function(){ return &function_s; }
338 private:
347 static double function_s( double x, void* params ){
348 Fcv<T,R,A>* const cl = reinterpret_cast<Fcv<T,R,A>*>( params );
349 return (cl->c.*cl->f)(x); }
353 T& c;
357 R (T::*f)(A) const volatile;
358 };
359#endif
360 base_F* f;
364 size_t* count;
365 public:
370 f = 0;
371 function = 0;
372 params = 0;
373 count = 0; // initially nullptr will do
374 }
379 explicit function_scl( gsl_function& v ){
380 // explicitly set f = 0 to indicate nothing to be deleted.
381 f = 0;
382 // copy
383 function = v.function;
384 params = v.params;
385 // just plausibly we could fail to allocate count: no further action needed.
386 count = new size_t;
387 *count = 1; // initially there is just one reference to f
388 }
395 template<typename A>
396 explicit function_scl( double (*const f)(A) ){
397 this->f = new Fx<A>( f );
398 params = this->f;
399 function = dynamic_cast<Fx<A>*>(this->f)->fn;
400 // just plausibly we could fail to allocate count: no further action needed.
401 count = new size_t;
402 *count = 1; // initially there is just one reference to f
403 }
410 template<typename A>
411 explicit function_scl( double const (*const f)(A) ){
412 this->f = new Fxc<A>( f );
413 params = this->f;
414 function = dynamic_cast<Fxc<A>*>(this->f)->fn;
415 // just plausibly we could fail to allocate count: no further action needed.
416 count = new size_t;
417 *count = 1; // initially there is just one reference to f
418 }
424 template<typename T, typename R, typename A> function_scl( T& c, R (T::*f)(A) ){
425 this->f = new F<T,R,A>( c, f );
426 params = this->f;
427 function = &fn;
428 // just plausibly we could fail to allocate count: no further action needed.
429 count = new size_t;
430 *count = 1; // initially there is just one reference to f
431 }
437 template<typename T, typename R, typename A> function_scl( T& c, R (T::*f)(A) const){
438 this->f = new Fc<T,R,A>( c, f );
439 params = this->f;
440 function = &fn;
441 // just plausibly we could fail to allocate count: no further action needed.
442 count = new size_t;
443 *count = 1; // initially there is just one reference to f
444 }
450 template<typename T, typename R, typename A> function_scl( T& c, R (T::*f)(A) volatile){
451 this->f = new Fv<T,R,A>( c, f );
452 params = this->f;
453 function = &fn;
454 // just plausibly we could fail to allocate count: no further action needed.
455 count = new size_t;
456 *count = 1; // initially there is just one reference to f
457 }
463 template<typename T, typename R, typename A> function_scl( T& c, R (T::*f)(A)
464 const volatile){
465 this->f = new Fcv<T,R,A>( c, f );
466 params = this->f;
467 function = &fn;
468 // just plausibly we could fail to allocate count: no further action needed.
469 count = new size_t;
470 *count = 1; // initially there is just one reference to f
471 }
472 // Copy and move constructors
473 // copy constructor
478 function_scl( function_scl const& v ) : f( v.f ), count( v.count ){
479 function = v.function;
480 params = v.params;
481 if( count != 0 ) ++*count; // function_scl is now shared.
482 }
483 // assignment operator
489 // first, possibly delete anything pointed to by this
490 if( count == 0 or --*count == 0 ){
491 delete f;
492 delete count;
493 }
494 // Then copy
495 f = v.f;
496 function = v.function;
497 params = v.params;
498 count = v.count;
499 if( count != 0 ) ++*count; // function_scl is now shared.
500 return *this;
501 }
502#ifdef __GXX_EXPERIMENTAL_CXX0X__
507 function_scl( function_scl&& v ) : f( v.f ), count( nullptr ){
508 std::swap( function, v.function );
509 std::swap( params, v.params );
510 std::swap( count, v.count );
511 v.f = nullptr;
512 }
519 std::swap( f, v.f );
520 std::swap( function, v.function );
521 std::swap( params, v.params );
522 std::swap( count, v.count );
523 return *this;
524 }
525#endif
530 // first, possibly delete anything pointed to by f
531 if( count == 0 or --*count == 0 ){
532 delete f;
533 delete count;
534 }
535 }
544 static double fn( double x, void* params ){
545 base_F* const b = reinterpret_cast<base_F*>( params );
546 return b->function()( x, params );
547 }
548 };
549
558 template<typename T, typename R, typename A>
559 inline function_scl make_function_scl( T& c, R (T::*f)(A) ){
560 function_scl fn( c, f );
561 return fn;
562 }
563#ifndef DOXYGEN_SKIP
569 template<typename T, typename R, typename A>
570 inline function_scl make_function_scl( T& c, R (T::*f)(A) const ){
571 function_scl fn( c, f );
572 return fn;
573 }
579 template<typename T, typename R, typename A>
580 inline function_scl make_function_scl( T& c, R (T::*f)(A) volatile ){
581 function_scl fn( c, f );
582 return fn;
583 }
589 template<typename T, typename R, typename A>
590 inline function_scl make_function_scl( T& c, R (T::*f)(A) const volatile ){
591 function_scl fn( c, f );
592 return fn;
593 }
600 inline double fn_eval( gsl_function const* const F, double const x ){
601 return (F->function)( x, F->params );
602 }
603#endif
610 inline double fn_eval( gsl_function const& F, double const x ){
611 return (F.function)( x, F.params );
612 }
613
614}
615
616#endif
Class that extends gsl_function so that it can be constructed from arbitrary function objects.
function_scl(double(*const f)(A))
Construct from a function.
function_scl(T &c, R(T::*f)(A) const)
Construct from a function object and a suitable const member function.
function_scl(gsl_function &v)
Could construct from a gsl_function.
function_scl(double const (*const f)(A))
Construct from a function.
function_scl & operator=(function_scl const &v)
The assignment operator.
function_scl(T &c, R(T::*f)(A) volatile)
Construct from a function object and a suitable volatile member function.
function_scl & operator=(function_scl &&v)
Move operator.
size_t * count
The shared reference count.
function_scl(function_scl const &v)
The copy constructor.
static double fn(double x, void *params)
This is the function that gsl_function points to if function_scl is constructed from a function objec...
function_scl()
The default constructor is only really useful for assigning to.
function_scl(T &c, R(T::*f)(A) const volatile)
Construct from a function object and a suitable const volatile member function.
function_scl(T &c, R(T::*f)(A))
Construct from a function object and a suitable non-const member function.
~function_scl()
The destructor unshares any shared resource.
function_scl(function_scl &&v)
Move constructor.
double F(double phi, double k, mode_t mode)
C++ version of gsl_sf_ellint_F().
Definition: sf_ellint.hpp:138
double b(int order, double qq)
C++ version of gsl_sf_mathieu_b().
Definition: sf_mathieu.hpp:298
The gsl package creates an interface to the GNU Scientific Library for C++.
Definition: blas.hpp:34
double fn_eval(gsl_function const &F, double const x)
Evaluate a gsl::function (or gsl_function).
function_scl make_function_scl(T &c, R(T::*f)(A))
Make a gsl::function_scl from a function object and a suitable non-const member function.