/* * This file is part of the DXX-Rebirth project . * It is copyright by its individual contributors, as recorded in the * project's Git history. See COPYING.txt at the top level for license * terms and a link to the Git history. */ #pragma once #include "dxxsconf.h" /* This header serves several purposes: * - Declare namespace dcx and add it to the list of searched * namespaces. * - If the compiler can disambiguate a namespace from a class inside a * searched namespace[1], declare dummy classes scoped so that * attempting to nest a namespace incorrectly causes a redefinition * error. The build would usually fail even without this forced * check, but the redefinition error forces a clear and immediate * report. * * If building game-specific code: * - #define dsx to a game-specific namespace: d1x or d2x, as * appropriate. * - Declare namespace dsx and add it to the list of searched * namespaces. When the dsx migration is finished, this `using * namespace` statement will be removed. * Otherwise: * - Declare dummy class dsx to force a redefinition error on attempts * to declare `namespace dsx` in common-only code. * * [1] gcc handles this in all tested versions. There are no known * clang versions which handle this. See the SConstruct test for * DXX_HAVE_CXX_DISAMBIGUATE_USING_NAMESPACE for how this is detected. */ #if defined(DXX_BUILD_DESCENT_I) || defined(DXX_BUILD_DESCENT_II) # if defined(DXX_BUILD_DESCENT_I) # define dsx d1x # else # define dsx d2x # endif /* The "X declared inside Y" comments are on the same line as their * declaration so that, if the compiler reports a redefinition error, * the output shows the comment, which explains which type of mistake is * being reported. */ namespace d1x { /* Force type mismatch on attempted nesting */ # ifdef DXX_HAVE_CXX_DISAMBIGUATE_USING_NAMESPACE class dcx; /* dcx declared inside d1x */ class d1x; /* d1x declared inside d1x */ class d2x; /* d2x declared inside d1x */ # endif } namespace d2x { /* Force type mismatch on attempted nesting */ # ifdef DXX_HAVE_CXX_DISAMBIGUATE_USING_NAMESPACE class dcx; /* dcx declared inside d2x */ class d1x; /* d1x declared inside d2x */ class d2x; /* d2x declared inside d2x */ # endif } #ifndef DXX_NO_USING_DSX /* For compatibility during migration, add namespace dsx to the search * list. This conflicts with the long term goal of the dsx project, but * is currently required for a successful build. * * When working on the dsx project, define this preprocessor symbol on a * file, then fix everything that breaks with that symbol defined. Move * on to the next file. When all files build with this symbol set, the * symbol and the using statement can be removed. */ using namespace dsx; // deprecated #endif #else /* This dummy class does not need to be guarded by * DXX_HAVE_CXX_DISAMBIGUATE_USING_NAMESPACE because it is declared only * when no other uses of `dsx` are present, so there is no ambiguity for * the compiler to resolve. */ class dsx; /* dsx declared in common-only code */ class d1x; /* d1x declared in common-only code */ class d2x; /* d2x declared in common-only code */ #endif #ifdef DXX_HAVE_CXX_DISAMBIGUATE_USING_NAMESPACE namespace dcx { /* Force type mismatch on attempted nesting */ class dcx; /* dcx declared inside dcx */ class d1x; /* d1x declared inside dcx */ class d2x; /* d2x declared inside dcx */ } namespace { class dcx; /* dcx declared inside anonymous */ class d1x; /* d1x declared inside anonymous */ class d2x; /* d2x declared inside anonymous */ } #else /* This empty namespace is required because, if * !DXX_HAVE_CXX_DISAMBIGUATE_USING_NAMESPACE, then no other declaration * of `namespace dcx` has been seen in this file. */ namespace dcx { } #endif using namespace dcx;