hoppy-generator-0.7.1: src/Foreign/Hoppy/Generator/Version.hs
-- This file is part of Hoppy.
--
-- Copyright 2015-2020 Bryan Gardiner <bog@khumba.net>
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU Affero General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU Affero General Public License for more details.
--
-- You should have received a copy of the GNU Affero General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
-- | Utilities for conditional compilation of parts of interfaces.
--
-- This module provides wrappers around 'Maybe' and 'catMaybes' so that you can
-- write code such as:
--
-- > myClass =
-- > makeClass ...
-- > [ ...ctors... ] $
-- > collect
-- > [ just $ mkMethod "foo" ...
-- > , test (apiVersion >= [1, 2]) $ mkMethod "bar" ...
-- > , test featureBaz $ mkMethod "baz" ...
-- > ]
module Foreign.Hoppy.Generator.Version (
-- * General filtering
Filtered,
collect,
none,
just,
test,
-- * C++ Standard version
CppVersion (..),
defaultCppVersion,
activeCppVersion,
) where
import Data.Maybe (catMaybes)
import System.Environment (lookupEnv)
import System.IO (hPutStrLn, stderr)
import System.IO.Unsafe (unsafePerformIO)
-- | Placeholder 'Maybe'-like type that may be more general in the future.
type Filtered = Maybe
-- | Filters a list of 'Filtered' values down to the elements that are actually
-- present.
collect :: [Filtered a] -> [a]
collect = catMaybes
-- | A 'Filtered' value that is always absent.
none :: Filtered a
none = Nothing
-- | Returns a 'Filtered' value that is always present.
just :: a -> Filtered a
just = Just
-- | Returns a 'Filtered' value that is only present if the boolean is true.
test :: Bool -> a -> Filtered a
test True = Just
test False = const Nothing
-- | Versions of the C++ standard.
data CppVersion =
Cpp1998
| Cpp2011
| Cpp2014
deriving (Bounded, Enum, Eq, Ord, Show)
-- | The 'CppVersion' chosen when one is not explicitly requested. This is
-- 'Cpp2011'.
defaultCppVersion :: CppVersion
defaultCppVersion = Cpp2011
-- | The active version of the C++ standard. This looks to the @HOPPY_CPP_STD@
-- environment variable, and accepts the values @c++98@, @c++11@, and @c++14@,
-- which map to the corresponding 'CppVersion' values. If a value other than
-- these is set, then a warning is printed and the default is used. If no value
-- is set, the default is used.
--
-- This uses 'unsafePerformIO' internally and won't cope with a changing
-- environment.
activeCppVersion :: CppVersion
{-# NOINLINE activeCppVersion #-}
activeCppVersion = unsafePerformIO $ do
strMaybe <- lookupEnv "HOPPY_CPP_STD"
case strMaybe of
Nothing -> return defaultCppVersion
Just "" -> return defaultCppVersion
Just "c++98" -> return Cpp1998
Just "c++11" -> return Cpp2011
Just "c++14" -> return Cpp2014
Just str -> do hPutStrLn stderr $ "Warning: Invalid HOPPY_CPP_STD value " ++ show str ++ "."
return defaultCppVersion