-- This file is part of Hoppy. -- -- Copyright 2015-2018 Bryan Gardiner -- -- 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 . -- | 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