macro (add_compiler_flags)
    foreach (flag ${ARGV})
        set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}")
    endforeach ()
endmacro ()

if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
    add_compiler_flags (-Werror)
    add_compiler_flags (-pedantic)
    add_compiler_flags (-pedantic-errors)
    add_compiler_flags (-fvisibility=hidden)
    add_compiler_flags (-fstrict-aliasing)
endif ()

if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
    add_compiler_flags (-Wall)
    add_compiler_flags (-Wextra)
    add_compiler_flags (-fdiagnostics-show-option)
    add_compiler_flags (-Wconversion)
    add_compiler_flags (-Wold-style-cast)
    add_compiler_flags (-Wfloat-equal)
    add_compiler_flags (-Wlogical-op)
    add_compiler_flags (-Wundef)
    add_compiler_flags (-Wredundant-decls)
    add_compiler_flags (-Wshadow)
    add_compiler_flags (-Wstrict-overflow=5)
    add_compiler_flags (-Wwrite-strings)
    add_compiler_flags (-Wpointer-arith)
    add_compiler_flags (-Wcast-qual)
    add_compiler_flags (-Wformat=2)
    add_compiler_flags (-Wswitch-default)
    add_compiler_flags (-Wmissing-include-dirs)
    add_compiler_flags (-Wcast-align)
    add_compiler_flags (-Wswitch-enum)
    add_compiler_flags (-Wnon-virtual-dtor)
    add_compiler_flags (-Wctor-dtor-privacy)
    add_compiler_flags (-Wsign-conversion)
    add_compiler_flags (-Wdisabled-optimization)
    add_compiler_flags (-Weffc++)
    add_compiler_flags (-Winline)
    add_compiler_flags (-Winvalid-pch)
    add_compiler_flags (-Wmissing-declarations)
    add_compiler_flags (-Woverloaded-virtual)

    if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.6)
        add_compiler_flags (-Wnoexcept)
    endif ()

    if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)
        add_compiler_flags (-Wdouble-promotion)
        add_compiler_flags (-Wtrampolines)
        add_compiler_flags (-Wzero-as-null-pointer-constant)
        add_compiler_flags (-Wuseless-cast)
        add_compiler_flags (-Wvector-operation-performance)
        add_compiler_flags (-Wsized-deallocation)
    endif ()

    if (CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 6.0 OR
        CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 6.0)
        add_compiler_flags (-Wshift-overflow=2)
        add_compiler_flags (-Wnull-dereference)
        add_compiler_flags (-Wduplicated-cond)
    endif ()
endif ()

if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
    add_compiler_flags (-Weverything)
    add_compiler_flags (-Qunused-arguments -fcolor-diagnostics)

    if (${CMAKE_CXX_STANDARD} MATCHES "11|14" AND
        ${CMAKE_CXX_STANDARD_REQUIRED})
        add_compiler_flags (-Wno-c++98-compat)
    endif ()
endif ()

