1 /*
2  fuzzylite (R), a fuzzy logic control library in C++.
3  Copyright (C) 2010-2017 FuzzyLite Limited. All rights reserved.
4  Author: Juan Rada-Vilela, Ph.D. <jcrada@fuzzylite.com>
5 
6  This file is part of fuzzylite.
7 
8  fuzzylite is free software: you can redistribute it and/or modify it under
9  the terms of the FuzzyLite License included with the software.
10 
11  You should have received a copy of the FuzzyLite License along with
12  fuzzylite. If not, see <http://www.fuzzylite.com/license/>.
13 
14  fuzzylite is a registered trademark of FuzzyLite Limited.
15  */
16 
17 #ifndef FL_FUZZYLITE_H
18 #define FL_FUZZYLITE_H
19 
20 #include <algorithm>
21 #include <cmath>
22 #include <iostream>
23 #include <sstream>
24 #include <limits>
25 #include <memory>
26 #include <cstddef>
27 
28 #ifndef FL_BUILD_PATH
29 #define FL_BUILD_PATH ""
30 #endif
31 
32 #if defined(_WIN32) || defined(WIN32)
33 #define FL_WINDOWS
34 #endif
35 
36 #if defined(unix) || defined(__unix__) || defined(__unix)
37 #define FL_UNIX
38 #endif
39 
40 #ifdef __APPLE__
41 #define FL_APPLE
42 #ifndef FL_UNIX
43 #define FL_UNIX
44 #endif
45 #endif
46 
47 #define FL__FILE__ std::string(__FILE__).substr(std::string(FL_BUILD_PATH).size())
48 
49 #define FL_LOG_PREFIX FL__FILE__ << " (" << __LINE__ << "):"
50 
51 #define FL_AT FL__FILE__, __LINE__, __FUNCTION__
52 
53 #define FL_LOG(message) {if (fl::fuzzylite::isLogging()){std::cout << FL_LOG_PREFIX << message << std::endl;}}
54 #define FL_LOGP(message) {if (fl::fuzzylite::isLogging()){std::cout << message << std::endl;}}
55 
56 #define FL_DEBUG_BEGIN if (fl::fuzzylite::isDebugging()){
57 #define FL_DEBUG_END }
58 
59 #define FL_DBG(message) FL_DEBUG_BEGIN\
60         std::cout << FL__FILE__ << "::" << __FUNCTION__ << "[" << __LINE__ << "]:" \
61                 << message << std::endl;\
62         FL_DEBUG_END
63 
64 
65 #ifdef FL_WINDOWS
66 #include <ciso646> //alternative operator spellings:
67 //#define and &&
68 //#define or ||
69 //#define not !
70 //#define bitand &
71 //#define bitor |
72 
73 //@todo: Address warning 4251 by exporting members?
74 //http://www.unknownroad.com/rtfm/VisualStudio/warningC4251.html
75 #ifdef _MSC_VER
76 #pragma warning (disable:4251)
77 #endif
78 
79 //fuzzylite as a shared library is exported
80 //Applications linking with fuzzylite as a shared library need to import
81 
82 //fuzzylite as a static library does not export or import
83 //Applications linking with fuzzylite as a static library do not import
84 
85 #if defined(FL_EXPORT_LIBRARY)
86 #define FL_API __declspec(dllexport)
87 #elif defined(FL_IMPORT_LIBRARY)
88 #define FL_API __declspec(dllimport)
89 #else
90 #define FL_API
91 #endif
92 
93 #else
94 #define FL_API
95 #endif
96 
97 /**
98   The fl namespace is the namespace where all the classes of the `fuzzylite`
99   library are contained in.
100 
101   @author Juan Rada-Vilela, Ph.D.
102   @since 4.0
103  */
104 namespace fl {
105     /**
106       Represents floating-point values (typedef to float or double).
107      */
108 #ifdef FL_USE_FLOAT
109     typedef float scalar;
110 #else
111     /**
112       Represents floating-point values as doubles.
113      */
114     typedef double scalar;
115 #endif
116 
117 #define FL_IUNUSED(x) (void) (x)
118 
119 #ifdef __GNUC__
120 #define FL_IUNUSED_DECL __attribute__((unused))
121 #else
122 #define FL_IUNUSED_DECL
123 #endif
124 
125     /**
126       Represents the Not-A-Number scalar value
127      */
128     const scalar nan FL_IUNUSED_DECL = std::numeric_limits<scalar>::quiet_NaN();
129     /**
130       Represents the infinity scalar value
131      */
132     const scalar inf FL_IUNUSED_DECL = std::numeric_limits<scalar>::infinity();
133 
134 #ifdef FL_CPP98
135     //C++98 defines
136 
137     //Pointers
138     /**
139       Represents the `C++11` or `C++98` null pointer depending on whether the
140       compilation flag `-DFL_CPP98` is set
141      */
142     const long null = 0L;
143 #define FL_unique_ptr std::auto_ptr
144 #define FL_move_ptr(x) x
145 
146     //Identifiers
147 #define FL_IOVERRIDE
148 #define FL_IFINAL
149 #define FL_IDEFAULT
150 #define FL_IDELETE
151 #define FL_INOEXCEPT throw()
152 #define FL_ITHREAD_LOCAL
153 
154     //Constructors
155 #define FL_DEFAULT_COPY(Class)
156 #define FL_DEFAULT_MOVE(Class)
157 #define FL_DEFAULT_COPY_AND_MOVE(Class)
158 
159 #define FL_DISABLE_COPY(Class) \
160     Class(const Class &);\
161     Class &operator=(const Class &);
162 
163 #else
164     //C++11 defines
165 
166     //Pointers
167     /**
168       Represents the `C++11` or `C++98` null pointer depending on whether the
169       compilation flag `-DFL_CPP98` is set
170      */
171     const std::nullptr_t null = nullptr;
172 #define FL_unique_ptr std::unique_ptr
173 #define FL_move_ptr(x) std::move(x)
174 
175     //Identifiers
176 #define FL_IOVERRIDE override
177 #define FL_IFINAL final
178 #define FL_IDEFAULT = default
179 #define FL_IDELETE = delete
180 #define FL_INOEXCEPT noexcept
181 #define FL_ITHREAD_LOCAL /*thread_local (commented for performance)*/
182 
183     //Constructors
184 #define FL_DEFAULT_COPY(Class) \
185     Class(const Class&) = default; \
186     Class& operator=(const Class&) = default;
187 #define FL_DEFAULT_MOVE(Class) \
188     Class(Class&&) = default; \
189     Class& operator=(Class&&) = default;
190 #define FL_DEFAULT_COPY_AND_MOVE(Class) \
191     Class(const Class&) = default; \
192     Class& operator=(const Class&) = default;\
193     Class(Class&&) = default; \
194     Class& operator=(Class&&) = default;
195 
196 #define FL_DISABLE_COPY(Class) \
197     Class(const Class &) = delete;\
198     Class &operator=(const Class &) = delete;
199 
200 #endif
201 
202 }
203 
204 
205 namespace fl {
206 
207     /**
208 
209       The fuzzylite class contains global settings and information about the
210       library.
211 
212       @author Juan Rada-Vilela, Ph.D.
213       @since 4.0
214 
215      */
216 
217     class FL_API fuzzylite {
218         friend class Operation;
219     private:
220         static int _decimals;
221         static scalar _macheps;
222         static std::ios_base::fmtflags _scalarFormat;
223         static bool _logging;
224         static bool _debugging;
225     public:
226         /**
227          Returns the name of the `fuzzylite` library
228          @return the name of the `fuzzylite` library
229          */
230         static std::string name();
231         /**
232           Returns the version of the `fuzzylite` library
233           @return the version of the `fuzzylite` library
234          */
235         static std::string version();
236         /**
237           Returns the name of the `fuzzylite` library including the version
238           @return the name of the `fuzzylite` library including the version
239          */
240         static std::string library();
241 
242         /**
243           Returns the license under which the `fuzzylite` library is released
244           @return the license under which the `fuzzylite` library is released
245          */
246         static std::string license();
247 
248         /**
249           Returns the name of the author of the `fuzzylite` library
250           @return "Juan Rada-Vilela, Ph.D."
251          */
252         static std::string author();
253 
254         /**
255           Returns the name of the company that owns the `fuzzylite` library
256           @return "FuzzyLite Limited"
257          */
258         static std::string company();
259 
260         /**
261           Returns the website of the `fuzzylite` library
262           @return "http://www.fuzzylite.com/"
263          */
264         static std::string website();
265 
266         /**
267          Returns the number of decimals utilized when formatting scalar values
268          @return the number of decimals utilized when formatting scalar values
269          (default is 3)
270          */
271         static int decimals();
272 
273         /**
274           Sets the number of decimals utilized when formatting scalar values
275           @param decimals is the number of decimals utilized when formatting
276           scalar values
277          */
278         static void setDecimals(int decimals);
279 
280         /**
281         Returns the minimum difference at which two floating-point values
282         are considered equivalent
283         @return the minimum difference at which two floating-point values
284         are considered equivalent (default is 1e-6)
285          */
286         static scalar macheps();
287 
288         /**
289           Sets the minimum difference at which two floating-point values are
290           considered equivalent
291           @param macheps is the minimum difference at which two floating-point
292           values are considered equivalent (default is 1e-6)
293          */
294         static void setMachEps(scalar macheps);
295 
296         /**
297           Sets the default format to be utilized for every fl::scalar passed to
298           Op::str()
299           @param scalarFormat is the format to be utilized for every fl::scalar
300           passed to Op::str()
301          */
302         static void setScalarFormat(std::ios_base::fmtflags scalarFormat);
303 
304         /**
305           Gets the default format to be utilized for every fl::scalar passed to
306           Op::str()
307           @return the format to be utilized for every fl::scalar passed to Op::str()
308          */
309         static std::ios_base::fmtflags scalarFormat();
310 
311         /**
312           Returns whether the library is logging information via the `FL_LOG`
313           macro
314           @return whether the library is logging information via the `FL_LOG`
315           macro
316          */
317         static bool isLogging();
318 
319         /**
320           Sets whether the library is set to log information using the macro
321           `FL_LOG`
322           @param logging indicates whether the library is set to log
323           information via the `FL_LOG` macro
324          */
325         static void setLogging(bool logging);
326 
327         /**
328           Indicates whether the library is running in debug mode
329           @return `true` if the library is running in debug mode, and `false`
330           if it is running in release mode
331          */
332         static bool isDebugging();
333 
334         /**
335           Sets whether the library is set to run in debug mode
336           @param debugging indicates whether the library is set to run in debug mode
337          */
338         static void setDebugging(bool debugging);
339 
340         /**
341           Returns the platform under which the `fuzzylite` library was built
342           @return `Unix` or `Windows`
343          */
344         static std::string platform();
345 
346         /**
347           Returns the name of the type of the floating-point variables
348           @return `double` or `float`
349          */
350         static std::string floatingPoint();
351     };
352 }
353 
354 
355 namespace fl {
356 
name()357     inline std::string fuzzylite::name() {
358         return "fuzzylite";
359     }
360 
library()361     inline std::string fuzzylite::library() {
362         return name() + " " + version();
363     }
364 
version()365     inline std::string fuzzylite::version() {
366         return "6.0";
367     }
368 
license()369     inline std::string fuzzylite::license() {
370         return "FuzzyLite License";
371     }
372 
author()373     inline std::string fuzzylite::author() {
374         return "Juan Rada-Vilela, Ph.D.";
375     }
376 
company()377     inline std::string fuzzylite::company() {
378         return "FuzzyLite Limited";
379     }
380 
website()381     inline std::string fuzzylite::website() {
382         return "http://www.fuzzylite.com/";
383     }
384 
setDebugging(bool debugging)385     inline void fuzzylite::setDebugging(bool debugging) {
386         _debugging = debugging;
387     }
388 
isDebugging()389     inline bool fuzzylite::isDebugging() {
390         return _debugging;
391     }
392 
setDecimals(int decimals)393     inline void fuzzylite::setDecimals(int decimals) {
394         _decimals = decimals;
395     }
396 
decimals()397     inline int fuzzylite::decimals() {
398         return _decimals;
399     }
400 
setScalarFormat(std::ios_base::fmtflags scalarFormat)401     inline void fuzzylite::setScalarFormat(std::ios_base::fmtflags scalarFormat) {
402         _scalarFormat = scalarFormat;
403     }
404 
scalarFormat()405     inline std::ios_base::fmtflags fuzzylite::scalarFormat() {
406         return _scalarFormat;
407     }
408 
setMachEps(scalar macheps)409     inline void fuzzylite::setMachEps(scalar macheps) {
410         _macheps = macheps;
411     }
412 
macheps()413     inline scalar fuzzylite::macheps() {
414         return _macheps;
415     }
416 
setLogging(bool logging)417     inline void fuzzylite::setLogging(bool logging) {
418         _logging = logging;
419     }
420 
isLogging()421     inline bool fuzzylite::isLogging() {
422         return _logging;
423     }
424 }
425 
426 #endif  /* FL_FUZZYLITE_H */
427 
428