You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

424 lines
14 KiB

  1. /* -*- c++ -*- (enables emacs c++ mode) */
  2. /*===========================================================================
  3. Copyright (C) 2002-2017 Yves Renard
  4. This file is a part of GetFEM++
  5. GetFEM++ is free software; you can redistribute it and/or modify it
  6. under the terms of the GNU Lesser General Public License as published
  7. by the Free Software Foundation; either version 3 of the License, or
  8. (at your option) any later version along with the GCC Runtime Library
  9. Exception either version 3.1 or (at your option) any later version.
  10. This program is distributed in the hope that it will be useful, but
  11. WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  12. or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
  13. License and GCC Runtime Library Exception for more details.
  14. You should have received a copy of the GNU Lesser General Public License
  15. along with this program; if not, write to the Free Software Foundation,
  16. Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
  17. As a special exception, you may use this file as it is a part of a free
  18. software library without restriction. Specifically, if other files
  19. instantiate templates or use macros or inline functions from this file,
  20. or you compile this file and link it with other files to produce an
  21. executable, this file does not by itself cause the resulting executable
  22. to be covered by the GNU Lesser General Public License. This exception
  23. does not however invalidate any other reasons why the executable file
  24. might be covered by the GNU Lesser General Public License.
  25. ===========================================================================*/
  26. /**@file gmm_std.h
  27. @author Yves Renard <Yves.Renard@insa-lyon.fr>,
  28. @author Julien Pommier <Julien.Pommier@insa-toulouse.fr>
  29. @date June 01, 1995.
  30. @brief basic setup for gmm (includes, typedefs etc.)
  31. */
  32. #ifndef GMM_STD_H__
  33. #define GMM_STD_H__
  34. // #include <getfem/getfem_arch_config.h>
  35. #ifndef __USE_STD_IOSTREAM
  36. # define __USE_STD_IOSTREAM
  37. #endif
  38. #ifndef __USE_BSD
  39. # define __USE_BSD
  40. #endif
  41. #ifndef __USE_ISOC99
  42. # define __USE_ISOC99
  43. #endif
  44. #if defined(_MSC_VER) && _MSC_VER >= 1400 // Secure versions for VC++
  45. # define GMM_SECURE_CRT
  46. # define SECURE_NONCHAR_SSCANF sscanf_s
  47. # define SECURE_NONCHAR_FSCANF fscanf_s
  48. # define SECURE_STRNCPY(a, la, b, lb) strncpy_s(a, la, b, lb)
  49. # define SECURE_FOPEN(F, filename, mode) (*(F) = 0, fopen_s(F, filename, mode))
  50. # define SECURE_SPRINTF1(S, l, st, p1) sprintf_s(S, l, st, p1)
  51. # define SECURE_SPRINTF2(S, l, st, p1, p2) sprintf_s(S, l, st, p1, p2)
  52. # define SECURE_SPRINTF4(S, l, st, p1, p2, p3, p4) sprintf_s(S, l, st, p1, p2, p3, p4)
  53. # define SECURE_STRDUP(s) _strdup(s)
  54. # ifndef _SCL_SECURE_NO_DEPRECATE
  55. # error Add the option /D_SCL_SECURE_NO_DEPRECATE to the compilation command
  56. # endif
  57. #else
  58. # define SECURE_NONCHAR_SSCANF sscanf
  59. # define SECURE_NONCHAR_FSCANF fscanf
  60. # define SECURE_STRNCPY(a, la, b, lb) strncpy(a, b, lb)
  61. # define SECURE_FOPEN(F, filename, mode) ((*(F)) = fopen(filename, mode))
  62. # define SECURE_SPRINTF1(S, l, st, p1) sprintf(S, st, p1)
  63. # define SECURE_SPRINTF2(S, l, st, p1, p2) sprintf(S, st, p1, p2)
  64. # define SECURE_SPRINTF4(S, l, st, p1, p2, p3, p4) sprintf(S, st, p1, p2, p3, p4)
  65. # define SECURE_STRDUP(s) strdup(s)
  66. #endif
  67. inline void GMM_NOPERATION_(int) { }
  68. #define GMM_NOPERATION(a) { GMM_NOPERATION_(abs(&(a) != &(a))); }
  69. /* ********************************************************************** */
  70. /* Compilers detection. */
  71. /* ********************************************************************** */
  72. /* for sun CC 5.0 ...
  73. #if defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x500
  74. # include <stdcomp.h>
  75. # undef _RWSTD_NO_CLASS_PARTIAL_SPEC
  76. # undef _RWSTD_NO_NAMESPACE
  77. #endif
  78. */
  79. /* for VISUAL C++ ...
  80. #if defined(_MSC_VER) // && !defined(__MWERKS__)
  81. #define _GETFEM_MSVCPP_ _MSC_VER
  82. #endif
  83. */
  84. #if defined(__GNUC__)
  85. # if (__GNUC__ < 4)
  86. # error : PLEASE UPDATE g++ TO AT LEAST 4.8 VERSION
  87. # endif
  88. #endif
  89. /* ********************************************************************** */
  90. /* C++ Standard Headers. */
  91. /* ********************************************************************** */
  92. #include <clocale>
  93. #include <cstdlib>
  94. #include <cstddef>
  95. #include <cmath>
  96. #include <cstring>
  97. #include <cctype>
  98. #include <cassert>
  99. #include <climits>
  100. #include <iostream>
  101. //#include <ios>
  102. #include <fstream>
  103. #include <ctime>
  104. #include <exception>
  105. #include <typeinfo>
  106. #include <stdexcept>
  107. #include <iterator>
  108. #include <algorithm>
  109. #include <vector>
  110. #include <deque>
  111. #include <string>
  112. #include <complex>
  113. #include <limits>
  114. #include <sstream>
  115. #include <numeric>
  116. #include <memory>
  117. #include <array>
  118. #include <locale.h>
  119. namespace std {
  120. #if defined(__GNUC__) && (__cplusplus <= 201103L)
  121. template<typename _Tp>
  122. struct _MakeUniq
  123. { typedef unique_ptr<_Tp> __single_object; };
  124. template<typename _Tp>
  125. struct _MakeUniq<_Tp[]>
  126. { typedef unique_ptr<_Tp[]> __array; };
  127. template<typename _Tp, size_t _Bound>
  128. struct _MakeUniq<_Tp[_Bound]>
  129. { struct __invalid_type { }; };
  130. /// std::make_unique for single objects
  131. template<typename _Tp, typename... _Args>
  132. inline typename _MakeUniq<_Tp>::__single_object
  133. make_unique(_Args&&... __args)
  134. { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); }
  135. /// std::make_unique for arrays of unknown bound
  136. template<typename _Tp>
  137. inline typename _MakeUniq<_Tp>::__array
  138. make_unique(size_t __num)
  139. { return unique_ptr<_Tp>(new typename remove_extent<_Tp>::type[__num]()); }
  140. /// Disable std::make_unique for arrays of known bound
  141. template<typename _Tp, typename... _Args>
  142. inline typename _MakeUniq<_Tp>::__invalid_type
  143. make_unique(_Args&&...) = delete;
  144. #endif
  145. // Should simply be replaced by std::shared_ptr<T[]> when it will be supported
  146. // by the STL
  147. template <typename T> class shared_array_ptr : shared_ptr<T> {
  148. public:
  149. shared_array_ptr() {}
  150. shared_array_ptr(T *q) : std::shared_ptr<T>(q, default_delete<T[]>()) {}
  151. template <typename Y> shared_array_ptr(const std::shared_ptr<Y> &p, T *q)
  152. : std::shared_ptr<T>(p, q) {}
  153. T *get() const { return shared_ptr<T>::get(); }
  154. T& operator*() const { return shared_ptr<T>::operator*(); }
  155. T* operator->() const { return shared_ptr<T>::operator->(); }
  156. };
  157. template <typename T> shared_array_ptr<T> make_shared_array(size_t num)
  158. { return shared_array_ptr<T>(new T[num]); }
  159. }
  160. #ifdef GETFEM_HAVE_OPENMP
  161. #include <omp.h>
  162. /**number of OpenMP threads*/
  163. inline size_t num_threads(){return omp_get_max_threads();}
  164. /**index of the current thread*/
  165. inline size_t this_thread() {return omp_get_thread_num();}
  166. /**is the program running in the parallel section*/
  167. inline bool me_is_multithreaded_now(){return static_cast<bool>(omp_in_parallel());}
  168. #else
  169. inline size_t num_threads(){return size_t(1);}
  170. inline size_t this_thread() {return size_t(0);}
  171. inline bool me_is_multithreaded_now(){return false;}
  172. #endif
  173. namespace gmm {
  174. using std::endl; using std::cout; using std::cerr;
  175. using std::ends; using std::cin; using std::isnan;
  176. #ifdef _WIN32
  177. class standard_locale {
  178. std::string cloc;
  179. std::locale cinloc;
  180. public :
  181. inline standard_locale(void) : cinloc(cin.getloc())
  182. {
  183. if (!me_is_multithreaded_now()){
  184. cloc=setlocale(LC_NUMERIC, 0);
  185. setlocale(LC_NUMERIC,"C");
  186. }
  187. }
  188. inline ~standard_locale() {
  189. if (!me_is_multithreaded_now())
  190. setlocale(LC_NUMERIC, cloc.c_str());
  191. }
  192. };
  193. #else
  194. /**this is the above solutions for linux, but I still needs to be tested.*/
  195. //class standard_locale {
  196. // locale_t oldloc;
  197. // locale_t temploc;
  198. //public :
  199. // inline standard_locale(void) : oldloc(uselocale((locale_t)0))
  200. // {
  201. // temploc = newlocale(LC_NUMERIC, "C", NULL);
  202. // uselocale(temploc);
  203. // }
  204. // inline ~standard_locale()
  205. // {
  206. // uselocale(oldloc);
  207. // freelocale(temploc);
  208. // }
  209. //};
  210. class standard_locale {
  211. std::string cloc;
  212. std::locale cinloc;
  213. public :
  214. inline standard_locale(void)
  215. : cloc(setlocale(LC_NUMERIC, 0)), cinloc(cin.getloc())
  216. { setlocale(LC_NUMERIC,"C"); cin.imbue(std::locale("C")); }
  217. inline ~standard_locale()
  218. { setlocale(LC_NUMERIC, cloc.c_str()); cin.imbue(cinloc); }
  219. };
  220. #endif
  221. class stream_standard_locale {
  222. std::locale cloc;
  223. std::ios &io;
  224. public :
  225. inline stream_standard_locale(std::ios &i)
  226. : cloc(i.getloc()), io(i) { io.imbue(std::locale("C")); }
  227. inline ~stream_standard_locale() { io.imbue(cloc); }
  228. };
  229. /* ******************************************************************* */
  230. /* Clock functions. */
  231. /* ******************************************************************* */
  232. # if defined(HAVE_SYS_TIMES)
  233. inline double uclock_sec(void) {
  234. static double ttclk = 0.;
  235. if (ttclk == 0.) ttclk = sysconf(_SC_CLK_TCK);
  236. tms t; times(&t); return double(t.tms_utime) / ttclk;
  237. }
  238. # else
  239. inline double uclock_sec(void)
  240. { return double(clock())/double(CLOCKS_PER_SEC); }
  241. # endif
  242. /* ******************************************************************** */
  243. /* Fixed size integer types. */
  244. /* ******************************************************************** */
  245. // Remark : the test program dynamic_array tests the length of
  246. // resulting integers
  247. template <size_t s> struct fixed_size_integer_generator {
  248. typedef void int_base_type;
  249. typedef void uint_base_type;
  250. };
  251. template <> struct fixed_size_integer_generator<sizeof(char)> {
  252. typedef signed char int_base_type;
  253. typedef unsigned char uint_base_type;
  254. };
  255. template <> struct fixed_size_integer_generator<sizeof(short int)
  256. - ((sizeof(short int) == sizeof(char)) ? 78 : 0)> {
  257. typedef signed short int int_base_type;
  258. typedef unsigned short int uint_base_type;
  259. };
  260. template <> struct fixed_size_integer_generator<sizeof(int)
  261. - ((sizeof(int) == sizeof(short int)) ? 59 : 0)> {
  262. typedef signed int int_base_type;
  263. typedef unsigned int uint_base_type;
  264. };
  265. template <> struct fixed_size_integer_generator<sizeof(long)
  266. - ((sizeof(int) == sizeof(long)) ? 93 : 0)> {
  267. typedef signed long int_base_type;
  268. typedef unsigned long uint_base_type;
  269. };
  270. template <> struct fixed_size_integer_generator<sizeof(long long)
  271. - ((sizeof(long long) == sizeof(long)) ? 99 : 0)> {
  272. typedef signed long long int_base_type;
  273. typedef unsigned long long uint_base_type;
  274. };
  275. typedef fixed_size_integer_generator<1>::int_base_type int8_type;
  276. typedef fixed_size_integer_generator<1>::uint_base_type uint8_type;
  277. typedef fixed_size_integer_generator<2>::int_base_type int16_type;
  278. typedef fixed_size_integer_generator<2>::uint_base_type uint16_type;
  279. typedef fixed_size_integer_generator<4>::int_base_type int32_type;
  280. typedef fixed_size_integer_generator<4>::uint_base_type uint32_type;
  281. typedef fixed_size_integer_generator<8>::int_base_type int64_type;
  282. typedef fixed_size_integer_generator<8>::uint_base_type uint64_type;
  283. // #if INT_MAX == 32767
  284. // typedef signed int int16_type;
  285. // typedef unsigned int uint16_type;
  286. // #elif SHRT_MAX == 32767
  287. // typedef signed short int int16_type;
  288. // typedef unsigned short int uint16_type;
  289. // #else
  290. // # error "impossible to build a 16 bits integer"
  291. // #endif
  292. // #if INT_MAX == 2147483647
  293. // typedef signed int int32_type;
  294. // typedef unsigned int uint32_type;
  295. // #elif SHRT_MAX == 2147483647
  296. // typedef signed short int int32_type;
  297. // typedef unsigned short int uint32_type;
  298. // #elif LONG_MAX == 2147483647
  299. // typedef signed long int int32_type;
  300. // typedef unsigned long int uint32_type;
  301. // #else
  302. // # error "impossible to build a 32 bits integer"
  303. // #endif
  304. // #if INT_MAX == 9223372036854775807L || INT_MAX == 9223372036854775807
  305. // typedef signed int int64_type;
  306. // typedef unsigned int uint64_type;
  307. // #elif LONG_MAX == 9223372036854775807L || LONG_MAX == 9223372036854775807
  308. // typedef signed long int int64_type;
  309. // typedef unsigned long int uint64_type;
  310. // #elif LLONG_MAX == 9223372036854775807LL || LLONG_MAX == 9223372036854775807L || LLONG_MAX == 9223372036854775807
  311. // typedef signed long long int int64_type;
  312. // typedef unsigned long long int uint64_type;
  313. // #else
  314. // # error "impossible to build a 64 bits integer"
  315. // #endif
  316. #if defined(__GNUC__) && !defined(__ICC)
  317. /*
  318. g++ can issue a warning at each usage of a function declared with this special attribute
  319. (also works with typedefs and variable declarations)
  320. */
  321. # define IS_DEPRECATED __attribute__ ((__deprecated__))
  322. /*
  323. the specified function is inlined at any optimization level
  324. */
  325. # define ALWAYS_INLINE __attribute__((always_inline))
  326. #else
  327. # define IS_DEPRECATED
  328. # define ALWAYS_INLINE
  329. #endif
  330. }
  331. /* ******************************************************************** */
  332. /* Import/export classes and interfaces from a shared library */
  333. /* ******************************************************************** */
  334. #if defined(EXPORTED_TO_SHARED_LIB)
  335. # if defined(_MSC_VER) || defined(__INTEL_COMPILER)
  336. # define APIDECL __declspec(dllexport)
  337. # elif defined(__GNUC__)
  338. # define __attribute__((visibility("default")))
  339. # else
  340. # define APIDECL
  341. # endif
  342. # if defined(IMPORTED_FROM_SHARED_LIB)
  343. # error INTENTIONAL COMPILCATION ERROR, DLL IMPORT AND EXPORT ARE INCOMPITABLE
  344. # endif
  345. #endif
  346. #if defined(IMPORTED_FROM_SHARED_LIB)
  347. # if defined(_MSC_VER) || defined(__INTEL_COMPILER)
  348. # define APIDECL __declspec(dllimport)
  349. # else
  350. # define APIDECL
  351. # endif
  352. # if defined(EXPORTED_TO_SHARED_LIB)
  353. # error INTENTIONAL COMPILCATION ERROR, DLL IMPORT AND EXPORT ARE INCOMPITABLE
  354. # endif
  355. #endif
  356. #ifndef EXPORTED_TO_SHARED_LIB
  357. # ifndef IMPORTED_FROM_SHARED_LIB
  358. # define APIDECL //empty, used during static linking
  359. # endif
  360. #endif
  361. #endif /* GMM_STD_H__ */