diff --git a/INSTALL b/INSTALL index bb2a59b5..001b971b 100644 --- a/INSTALL +++ b/INSTALL @@ -15,7 +15,8 @@ conda install -c conda-forge simuPOP ### Compile from source If you are working with a development version of simuPOP or an unsupported platform, you may need to install simuPOP from source. -Generally speaking, you will need a C/C++ compiler and zlib. + +Generally speaking, you will need a recent C/C++ compiler that supports the `c++17` standard and zlib. #### Checkout the simuPOP source code diff --git a/README.md b/README.md index d07a8b84..d2cf9138 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,9 @@ The user guide and reference manual of simuPOP is available at http://bopeng.git ## Change Log since 1.1.7 +### simuPOP 1.1.16 +* [#103](https://github.com/BoPeng/simuPOP/issues/103) Fix compatibility with recent compilers with c++17 support, and fix conda-forge release. + ### simuPOP 1.1.15 * [#122](https://github.com/BoPeng/simuPOP/issues/122) Fix compatibility with Visual Studio 2022 under windows. diff --git a/setup.py b/setup.py index 3e52a961..1dbe70c6 100755 --- a/setup.py +++ b/setup.py @@ -79,7 +79,7 @@ def is_maverick(): fin, fout, ferr = (p.stdin, p.stdout, p.stderr) output = ferr.readlines()[-1].decode('utf8') try: - version = re.match('.*gcc version\s*(\d+).(\d+).(\d+).*', output).groups() + version = re.match(r'.*gcc version\s*(\d+).(\d+).(\d+).*', output).groups() if int(version[0]) < 4 or int(version[1]) < 2: print('Support for openMP is turned off because version %s.%s.%s of gcc does not support this feature' % version) USE_OPENMP = False @@ -402,6 +402,8 @@ def replaceIntHeader(file): COMMON_MACROS = [ ('BOOST_UBLAS_NDEBUG', None), + ('BOOST_NO_CXX98_FUNCTION_BASE', None), + ('BOOST_COMPUTE_USE_CPP11', None), ('_HAS_ITERATOR_DEBUGGING', 0), ('BOOST_ALL_NO_LIB', None), ('NO_ZLIB', 0), @@ -490,7 +492,7 @@ def replaceIntHeader(file): # /wd4819 disables warning messages for non-unicode character in boost/uitlity/enable_if.hpp # /wd4996 disables warning messages for unsafe function call in boost/serialization # /wd4068 disables warning messages for unknown pragma set by gcc - common_extra_compile_args = ['/O2', '/GR', '/EHsc', '/wd4819', '/wd4996', '/wd4068'] + common_extra_compile_args = ['/O2', '/GR', '/EHsc', '/wd4819', '/wd4996', '/wd4068', '/std:c++17'] # Enable openMP if USE_OPENMP = True if USE_OPENMP: if USE_ICC: @@ -535,6 +537,7 @@ def try_compile(body='', ext='.cpp'): oldstderr = os.dup(sys.stderr.fileno()) os.dup2(devnull.fileno(), sys.stderr.fileno()) cc = new_compiler() + distutils.sysconfig.customize_compiler(cc) objects = cc.compile([fname], output_dir=tmpdir) except: return False @@ -650,6 +653,7 @@ def ModuInfo(modu, SIMUPOP_VER, SIMUPOP_REV): # try to get print('Building static libraries') c = new_compiler(verbose=1) + distutils.sysconfig.customize_compiler(c) # -w suppress all warnings caused by the use of boost libraries objects = c.compile(LIB_FILES, include_dirs=['gsl', 'gsl/specfunc', 'build', '.', boost_include_dir] + common_extra_include_dirs, diff --git a/src/customizedTemplates.cpp b/src/customizedTemplates.cpp index 2598be31..6eccfce8 100644 --- a/src/customizedTemplates.cpp +++ b/src/customizedTemplates.cpp @@ -63,7 +63,7 @@ template PyObject * getarrayitem_template(struct arrayobject_template * op, Py_ssize_t i) { - register struct arrayobject_template * ap; + struct arrayobject_template * ap; assert(is_carrayobject_template(op)); ap = (struct arrayobject_template *)op; @@ -77,7 +77,7 @@ template <> PyObject * getarrayitem_template(struct arrayobject_template * op, Py_ssize_t i) { - register struct arrayobject_template * ap; + struct arrayobject_template * ap; assert(is_carrayobject_template(op)); ap = (struct arrayobject_template *)op; @@ -746,7 +746,7 @@ template PyObject * getarrayitem_template(PyObject * op, Py_ssize_t i) { - register struct arrayobject_template * ap; + struct arrayobject_template * ap; assert(is_carrayobject_template(op)); ap = (struct arrayobject_template *)op; @@ -1485,7 +1485,7 @@ template <> PyObject * getarrayitem_template(PyObject * op, Py_ssize_t i) { - register struct arrayobject_template * ap; + struct arrayobject_template * ap; assert(is_carrayobject_template(op)); ap = (struct arrayobject_template *)op; diff --git a/src/simuPOP_cfg.h b/src/simuPOP_cfg.h index 585fd6eb..78417ab0 100644 --- a/src/simuPOP_cfg.h +++ b/src/simuPOP_cfg.h @@ -213,7 +213,8 @@ typedef const unsigned char & ConstAlleleRef; // max allowed allele state extern const unsigned long ModuleMaxAllele; -extern const unsigned long MaxRandomNumber; +// extern const unsigned long MaxRandomNumber; +inline constexpr unsigned long MaxRandomNumber = std::numeric_limits::max(); #define PopSWIGType "simuPOP::Population *" #define IndSWIGType "simuPOP::Individual *" diff --git a/src/stator.h b/src/stator.h index 0ac0640e..c26d6ff8 100644 --- a/src/stator.h +++ b/src/stator.h @@ -37,7 +37,6 @@ #include using std::string; using std::count_if; -using std::bind2nd; using std::equal; using std::greater; using std::min; diff --git a/src/utility.cpp b/src/utility.cpp index 3db6e766..17e9cd2a 100644 --- a/src/utility.cpp +++ b/src/utility.cpp @@ -149,7 +149,6 @@ using std::greater; const Allele simuPOP::vectorm::zero_ = 0; #endif const unsigned long ModuleMaxAllele = std::numeric_limits::max(); -const unsigned long MaxRandomNumber = std::numeric_limits::max(); const unsigned char MaxTraitIndex = std::numeric_limits::max(); const size_t InvalidValue = ~size_t(0); const size_t MaxIndexSize = std::numeric_limits::max(); diff --git a/src/utility.h b/src/utility.h index 6769ae26..3aa5bbeb 100644 --- a/src/utility.h +++ b/src/utility.h @@ -1775,13 +1775,37 @@ void closeOutput(const string & output = string()); class RNG_func { public: + typedef unsigned long int result_type; + RNG_func(gsl_rng * rng) : m_RNG(rng) { } - unsigned long int operator()(unsigned long int N) const +#ifdef BOOST_COMPUTE_USE_CPP11 + // somehow these functions needs to be static (callable from class), so + // min/max cannot change with the underlying m_RNG. However, we demand that + // RNGs generate full range of int to have a minimal range from 0 to + // MaxRandomNumber, so we can set the max to MaxRandomNumber. + constexpr static result_type min() + { + return 0; + } + + constexpr static result_type max() + { + return MaxRandomNumber - 1; + } + + result_type operator()() + { + return gsl_rng_uniform_int(m_RNG, MaxRandomNumber); + } + +#endif + + result_type operator()(result_type N) const { return gsl_rng_uniform_int(m_RNG, N); } @@ -1981,7 +2005,12 @@ class RNG // generator. RNG_func rng(m_RNG); +#ifdef BOOST_COMPUTE_USE_CPP11 + std::shuffle(begin, end, rng); +#else std::random_shuffle(begin, end, rng); +#endif + }