build: require gcc >= 5.3 and switch to C++14

Change-Id: I53ecd93b5666f451129afbe7ba02de357218efb5
Refs: #4462, #3076
diff --git a/.jenkins.d/README.md b/.jenkins.d/README.md
index 41812aa..39fa40b 100644
--- a/.jenkins.d/README.md
+++ b/.jenkins.d/README.md
@@ -13,13 +13,13 @@
 
   * `[OS_TYPE]`: `Linux`
   * `[DISTRO_TYPE]`: `Ubuntu`
-  * `[DISTRO_VERSION]`: `Ubuntu-14.04`, `Ubuntu-16.04`
+  * `[DISTRO_VERSION]`: `Ubuntu-16.04`, `Ubuntu-18.04`
 
   Possible values for OS X / macOS:
 
   * `[OS_TYPE]`: `OSX`
   * `[DISTRO_TYPE]`: `OSX` (can be absent)
-  * `[DISTRO_VERSION]`: `OSX-10.10`, `OSX-10.11`, `OSX-10.12`
+  * `[DISTRO_VERSION]`: `OSX-10.11`, `OSX-10.12`, `OSX-10.13`
 
 - `JOB_NAME`: optional variable to define type of the job.  Depending on the defined job type,
   the build scripts can perform different tasks.
diff --git a/.travis.yml b/.travis.yml
index d378bfe..984e8ac 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,5 +1,5 @@
 language: cpp
-dist: trusty
+dist: xenial
 sudo: required
 env:
   global:
@@ -11,80 +11,34 @@
     # Linux/gcc
     # https://launchpad.net/~ubuntu-toolchain-r/+archive/ubuntu/test/+packages
     - os: linux
-      env: COMPILER=g++-4.8
-    - os: linux
-      env: COMPILER=g++-4.9
-      addons:
-        apt:
-          sources: ubuntu-toolchain-r-test
-          packages: g++-4.9
-    - os: linux
       env: COMPILER=g++-5
-      addons:
-        apt:
-          sources: ubuntu-toolchain-r-test
-          packages: g++-5
     - os: linux
       env: COMPILER=g++-6
-      addons:
-        apt:
-          sources: ubuntu-toolchain-r-test
-          packages: g++-6
     - os: linux
       env: COMPILER=g++-7
-      addons:
-        apt:
-          sources: ubuntu-toolchain-r-test
-          packages: g++-7
+    - os: linux
+      env: COMPILER=g++-8
 
     # Linux/clang
     # https://apt.llvm.org/
     - os: linux
       env: COMPILER=clang++-3.5
-      addons:
-        apt:
-          packages: clang-3.5
     - os: linux
       env: COMPILER=clang++-3.6
-      addons:
-        apt:
-          packages: clang-3.6
     - os: linux
       env: COMPILER=clang++-3.7 DISABLE_ASAN=yes
-      addons:
-        apt:
-          sources: ["llvm-toolchain-precise-3.7", "ubuntu-toolchain-r-test"]
-          packages: clang-3.7
     - os: linux
       env: COMPILER=clang++-3.8
-      addons:
-        apt:
-          sources: ["llvm-toolchain-precise-3.8", "ubuntu-toolchain-r-test"]
-          packages: clang-3.8
     - os: linux
-      env: COMPILER=clang++-3.9 DISABLE_ASAN=yes
-      addons:
-        apt:
-          sources: ["llvm-toolchain-trusty-3.9", "ubuntu-toolchain-r-test"]
-          packages: clang-3.9
+      env: COMPILER=clang++-3.9
     - os: linux
       env: COMPILER=clang++-4.0
-      addons:
-        apt:
-          sources: ["llvm-toolchain-trusty-4.0", "ubuntu-toolchain-r-test"]
-          packages: clang-4.0
     - os: linux
       env: COMPILER=clang++-5.0
-      addons:
-        apt:
-          sources: ["llvm-toolchain-trusty-5.0", "ubuntu-toolchain-r-test"]
-          packages: clang-5.0
     - os: linux
       env: COMPILER=clang++-6.0
-      addons:
-        apt:
-          sources: ["llvm-toolchain-trusty-6.0", "ubuntu-toolchain-r-test"]
-          packages: clang-6.0
+    - os: linux
+      env: COMPILER=clang++-7
 
     # macOS/clang
     # https://docs.travis-ci.com/user/reference/osx/#OS-X-Version
@@ -95,14 +49,45 @@
       osx_image: xcode8.3
       env: OSX_VERSION=10.12
     - os: osx
-      osx_image: xcode9.2
-      env: OSX_VERSION=10.12
-    - os: osx
-      osx_image: xcode9.3beta
+      osx_image: xcode9.3
       env: OSX_VERSION=10.13
 
+  allow_failures:
+    - env: COMPILER=g++-6
+    - env: COMPILER=g++-7
+    - env: COMPILER=g++-8
+    - env: COMPILER=clang++-3.5
+    - env: COMPILER=clang++-3.6
+    - env: COMPILER=clang++-3.7 DISABLE_ASAN=yes
+    - env: COMPILER=clang++-3.8
+    - env: COMPILER=clang++-3.9
+    - env: COMPILER=clang++-4.0
+    - env: COMPILER=clang++-5.0
+    - env: COMPILER=clang++-6.0
+    - env: COMPILER=clang++-7
+
+  fast_finish: true
+
+install: |
+    case ${COMPILER} in
+      g++-[6789])
+        travis_retry sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
+        travis_retry sudo apt-get -qq update
+        travis_retry sudo apt-get -qy install "${COMPILER}"
+        ;;
+      clang++-*)
+        CLANG_VERSION=${COMPILER/clang++}
+        if [[ ${CLANG_VERSION} != "-3."* ]]; then
+          wget -O - "https://apt.llvm.org/llvm-snapshot.gpg.key" | sudo apt-key add -
+          travis_retry sudo add-apt-repository -y "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial${CLANG_VERSION/-7} main"
+        fi
+        travis_retry sudo apt-get -qq update
+        travis_retry sudo apt-get -qy install "clang${CLANG_VERSION}"
+        ;;
+    esac
+
 before_script:
-  - if [[ ${TRAVIS_OS_NAME} == linux ]]; then export NODE_LABELS="Linux Ubuntu Ubuntu-14.04"; fi
+  - if [[ ${TRAVIS_OS_NAME} == linux ]]; then export NODE_LABELS="Linux Ubuntu Ubuntu-16.04"; fi
   - if [[ ${TRAVIS_OS_NAME} == osx ]]; then export NODE_LABELS="OSX OSX-${OSX_VERSION}"; fi
   - if [[ -n ${COMPILER} ]]; then export CXX=${COMPILER}; fi
   - ${CXX:-c++} --version
diff --git a/.waf-tools/default-compiler-flags.py b/.waf-tools/default-compiler-flags.py
index bba2b1e..e690290 100644
--- a/.waf-tools/default-compiler-flags.py
+++ b/.waf-tools/default-compiler-flags.py
@@ -1,44 +1,45 @@
 # -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
 
-from waflib import Logs, Configure, Utils
+from waflib import Configure, Logs, Utils
 
 def options(opt):
-    opt.add_option('--debug', '--with-debug', action='store_true', default=False, dest='debug',
-                   help='''Compile in debugging mode with minimal optimizations (-O0 or -Og)''')
+    opt.add_option('--debug', '--with-debug', action='store_true', default=False,
+                   help='Compile in debugging mode with minimal optimizations (-O0 or -Og)')
 
 def configure(conf):
     conf.start_msg('Checking C++ compiler version')
 
-    cxx = conf.env['CXX_NAME'] # CXX_NAME is the generic name of the compiler
-    ccver = tuple(int(i) for i in conf.env['CC_VERSION'])
+    cxx = conf.env.CXX_NAME # generic name of the compiler
+    ccver = tuple(int(i) for i in conf.env.CC_VERSION)
+    ccverstr = '.'.join(conf.env.CC_VERSION)
     errmsg = ''
     warnmsg = ''
     if cxx == 'gcc':
-        if ccver < (4, 8, 2):
+        if ccver < (5, 3, 0):
             errmsg = ('The version of gcc you are using is too old.\n'
-                      'The minimum supported gcc version is 4.8.2.')
+                      'The minimum supported gcc version is 5.3.0.')
         conf.flags = GccFlags()
     elif cxx == 'clang':
-        if ccver < (3, 4, 0):
+        if ccver < (3, 5, 0):
             errmsg = ('The version of clang you are using is too old.\n'
-                      'The minimum supported clang version is 3.4.0.')
+                      'The minimum supported clang version is 3.5.0.')
         conf.flags = ClangFlags()
     else:
         warnmsg = 'Note: %s compiler is unsupported' % cxx
         conf.flags = CompilerFlags()
 
     if errmsg:
-        conf.end_msg('.'.join(conf.env['CC_VERSION']), color='RED')
+        conf.end_msg(ccverstr, color='RED')
         conf.fatal(errmsg)
     elif warnmsg:
-        conf.end_msg('.'.join(conf.env['CC_VERSION']), color='YELLOW')
+        conf.end_msg(ccverstr, color='YELLOW')
         Logs.warn(warnmsg)
     else:
-        conf.end_msg('.'.join(conf.env['CC_VERSION']))
+        conf.end_msg(ccverstr)
 
     conf.areCustomCxxflagsPresent = (len(conf.env.CXXFLAGS) > 0)
 
-    # General flags are always applied (e.g., selecting C++11 mode)
+    # General flags are always applied (e.g., selecting C++ language standard)
     generalFlags = conf.flags.getGeneralFlags(conf)
     conf.add_supported_cxxflags(generalFlags['CXXFLAGS'])
     conf.add_supported_linkflags(generalFlags['LINKFLAGS'])
@@ -53,10 +54,10 @@
         extraFlags = conf.flags.getDebugFlags(conf)
         if conf.areCustomCxxflagsPresent:
             missingFlags = [x for x in extraFlags['CXXFLAGS'] if x not in conf.env.CXXFLAGS]
-            if len(missingFlags) > 0:
-                Logs.warn("Selected debug mode, but CXXFLAGS is set to a custom value '%s'"
-                          % " ".join(conf.env.CXXFLAGS))
-                Logs.warn("Default flags '%s' are not activated" % " ".join(missingFlags))
+            if missingFlags:
+                Logs.warn('Selected debug mode, but CXXFLAGS is set to a custom value "%s"'
+                          % ' '.join(conf.env.CXXFLAGS))
+                Logs.warn('Default flags "%s" will not be used' % ' '.join(missingFlags))
     else:
         extraFlags = conf.flags.getOptimizedFlags(conf)
 
@@ -106,6 +107,9 @@
 
 
 class CompilerFlags(object):
+    def getCompilerVersion(self, conf):
+        return tuple(int(i) for i in conf.env.CC_VERSION)
+
     def getGeneralFlags(self, conf):
         """Get dict of CXXFLAGS, LINKFLAGS, and DEFINES that are always needed"""
         return {'CXXFLAGS': [], 'LINKFLAGS': [], 'DEFINES': []}
@@ -124,7 +128,7 @@
     """
     def getGeneralFlags(self, conf):
         flags = super(GccBasicFlags, self).getGeneralFlags(conf)
-        flags['CXXFLAGS'] += ['-std=c++11']
+        flags['CXXFLAGS'] += ['-std=c++14']
         return flags
 
     def getDebugFlags(self, conf):
@@ -160,25 +164,19 @@
 class GccFlags(GccBasicFlags):
     def getDebugFlags(self, conf):
         flags = super(GccFlags, self).getDebugFlags(conf)
-        version = tuple(int(i) for i in conf.env['CC_VERSION'])
-        if version < (5, 1, 0):
-            flags['CXXFLAGS'] += ['-Wno-missing-field-initializers']
-        flags['CXXFLAGS'] += ['-fdiagnostics-color'] # gcc >= 4.9
+        flags['CXXFLAGS'] += ['-fdiagnostics-color']
         return flags
 
     def getOptimizedFlags(self, conf):
         flags = super(GccFlags, self).getOptimizedFlags(conf)
-        version = tuple(int(i) for i in conf.env['CC_VERSION'])
-        if version < (5, 1, 0):
-            flags['CXXFLAGS'] += ['-Wno-missing-field-initializers']
-        flags['CXXFLAGS'] += ['-fdiagnostics-color'] # gcc >= 4.9
+        flags['CXXFLAGS'] += ['-fdiagnostics-color']
         return flags
 
 class ClangFlags(GccBasicFlags):
     def getGeneralFlags(self, conf):
         flags = super(ClangFlags, self).getGeneralFlags(conf)
-        version = tuple(int(i) for i in conf.env['CC_VERSION'])
-        if Utils.unversioned_sys_platform() == 'darwin' and version >= (9, 0, 0): # Bug #4296
+        if Utils.unversioned_sys_platform() == 'darwin' and self.getCompilerVersion(conf) >= (9, 0, 0):
+            # Bug #4296
             flags['CXXFLAGS'] += [['-isystem', '/usr/local/include'], # for Homebrew
                                   ['-isystem', '/opt/local/include']] # for MacPorts
         return flags
@@ -194,7 +192,7 @@
                               '-Wno-error=unneeded-internal-declaration', # Bug #1588
                               '-Wno-unused-local-typedef', # Bugs #2657 and #3209
                               ]
-        version = tuple(int(i) for i in conf.env['CC_VERSION'])
+        version = self.getCompilerVersion(conf)
         if version < (3, 9, 0) or (Utils.unversioned_sys_platform() == 'darwin' and version < (8, 1, 0)):
             flags['CXXFLAGS'] += ['-Wno-unknown-pragmas']
         return flags
@@ -206,7 +204,7 @@
                               '-Wundefined-func-template',
                               '-Wno-unused-local-typedef', # Bugs #2657 and #3209
                               ]
-        version = tuple(int(i) for i in conf.env['CC_VERSION'])
+        version = self.getCompilerVersion(conf)
         if version < (3, 9, 0) or (Utils.unversioned_sys_platform() == 'darwin' and version < (8, 1, 0)):
             flags['CXXFLAGS'] += ['-Wno-unknown-pragmas']
         return flags