Multiple variable template specializations with std::enable_if












0















I'm trying to concisely define a variable template with these effective values:



// (template<typename T> constexpr T EXP = std::numeric_limits<T>::max_exponent / 2;)

// float and double scalar definitions:
const double huge = std::scalbn(1, EXP<double>);
const float huge = std::scalbn(1, EXP<float>);
// SIMD vector definitions:
const Vec8f huge = Vec8f(huge<float>); // vector of 8 floats
const Vec8d huge = Vec8d(huge<double>); // vector of 8 doubles
const Vec4f huge = Vec4f(huge<float>); // vector of 4 floats
// Integral types should fail to compile


The VecXX vector definitions (SIMD vectors) need to use the corresponding scalar type as shown (e.g. huge<float> for vector of floats). This is available as VecXX::value_type or through a type traits-style template class (VectorTraits<VecXX>::value_type).



Ideally I think I'd have something like:



// Primary. What should go here? I want all other types to not compile
template<typename T, typename Enabler = void>
const T huge = T{ 0 };

// Scalar specialization for floating point types:
template<typename T>
const T huge<T> = std::enable_if_t<std::is_floating_point<T>::value, T>(std::scalbn(1, EXP<T>));

// Vector specialization, uses above declaration for corresponding FP type
template<typename T>
const T huge<T> = std::enable_if_t<VectorTraits<T>::is_vector, T>(huge<VectorTraits<T>::scalar_type>);


but I can't quite figure out a working version (above fails with "redefinition of const T huge<T>"). What's the best way to do this?










share|improve this question





























    0















    I'm trying to concisely define a variable template with these effective values:



    // (template<typename T> constexpr T EXP = std::numeric_limits<T>::max_exponent / 2;)

    // float and double scalar definitions:
    const double huge = std::scalbn(1, EXP<double>);
    const float huge = std::scalbn(1, EXP<float>);
    // SIMD vector definitions:
    const Vec8f huge = Vec8f(huge<float>); // vector of 8 floats
    const Vec8d huge = Vec8d(huge<double>); // vector of 8 doubles
    const Vec4f huge = Vec4f(huge<float>); // vector of 4 floats
    // Integral types should fail to compile


    The VecXX vector definitions (SIMD vectors) need to use the corresponding scalar type as shown (e.g. huge<float> for vector of floats). This is available as VecXX::value_type or through a type traits-style template class (VectorTraits<VecXX>::value_type).



    Ideally I think I'd have something like:



    // Primary. What should go here? I want all other types to not compile
    template<typename T, typename Enabler = void>
    const T huge = T{ 0 };

    // Scalar specialization for floating point types:
    template<typename T>
    const T huge<T> = std::enable_if_t<std::is_floating_point<T>::value, T>(std::scalbn(1, EXP<T>));

    // Vector specialization, uses above declaration for corresponding FP type
    template<typename T>
    const T huge<T> = std::enable_if_t<VectorTraits<T>::is_vector, T>(huge<VectorTraits<T>::scalar_type>);


    but I can't quite figure out a working version (above fails with "redefinition of const T huge<T>"). What's the best way to do this?










    share|improve this question



























      0












      0








      0








      I'm trying to concisely define a variable template with these effective values:



      // (template<typename T> constexpr T EXP = std::numeric_limits<T>::max_exponent / 2;)

      // float and double scalar definitions:
      const double huge = std::scalbn(1, EXP<double>);
      const float huge = std::scalbn(1, EXP<float>);
      // SIMD vector definitions:
      const Vec8f huge = Vec8f(huge<float>); // vector of 8 floats
      const Vec8d huge = Vec8d(huge<double>); // vector of 8 doubles
      const Vec4f huge = Vec4f(huge<float>); // vector of 4 floats
      // Integral types should fail to compile


      The VecXX vector definitions (SIMD vectors) need to use the corresponding scalar type as shown (e.g. huge<float> for vector of floats). This is available as VecXX::value_type or through a type traits-style template class (VectorTraits<VecXX>::value_type).



      Ideally I think I'd have something like:



      // Primary. What should go here? I want all other types to not compile
      template<typename T, typename Enabler = void>
      const T huge = T{ 0 };

      // Scalar specialization for floating point types:
      template<typename T>
      const T huge<T> = std::enable_if_t<std::is_floating_point<T>::value, T>(std::scalbn(1, EXP<T>));

      // Vector specialization, uses above declaration for corresponding FP type
      template<typename T>
      const T huge<T> = std::enable_if_t<VectorTraits<T>::is_vector, T>(huge<VectorTraits<T>::scalar_type>);


      but I can't quite figure out a working version (above fails with "redefinition of const T huge<T>"). What's the best way to do this?










      share|improve this question
















      I'm trying to concisely define a variable template with these effective values:



      // (template<typename T> constexpr T EXP = std::numeric_limits<T>::max_exponent / 2;)

      // float and double scalar definitions:
      const double huge = std::scalbn(1, EXP<double>);
      const float huge = std::scalbn(1, EXP<float>);
      // SIMD vector definitions:
      const Vec8f huge = Vec8f(huge<float>); // vector of 8 floats
      const Vec8d huge = Vec8d(huge<double>); // vector of 8 doubles
      const Vec4f huge = Vec4f(huge<float>); // vector of 4 floats
      // Integral types should fail to compile


      The VecXX vector definitions (SIMD vectors) need to use the corresponding scalar type as shown (e.g. huge<float> for vector of floats). This is available as VecXX::value_type or through a type traits-style template class (VectorTraits<VecXX>::value_type).



      Ideally I think I'd have something like:



      // Primary. What should go here? I want all other types to not compile
      template<typename T, typename Enabler = void>
      const T huge = T{ 0 };

      // Scalar specialization for floating point types:
      template<typename T>
      const T huge<T> = std::enable_if_t<std::is_floating_point<T>::value, T>(std::scalbn(1, EXP<T>));

      // Vector specialization, uses above declaration for corresponding FP type
      template<typename T>
      const T huge<T> = std::enable_if_t<VectorTraits<T>::is_vector, T>(huge<VectorTraits<T>::scalar_type>);


      but I can't quite figure out a working version (above fails with "redefinition of const T huge<T>"). What's the best way to do this?







      c++ c++14 sfinae enable-if variable-templates






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Dec 31 '18 at 9:30







      ZachB

















      asked Dec 30 '18 at 23:42









      ZachBZachB

      5,31413159




      5,31413159
























          2 Answers
          2






          active

          oldest

          votes


















          2














          Not exactly what you asked but I hope the following example can show you how to use SFINAE to specialize a template variable



          template <typename T, typename = void>
          constexpr T huge = T{0};

          template <typename T>
          constexpr T huge<T, std::enable_if_t<std::is_floating_point<T>{}>> = T{1};

          template <typename T>
          constexpr T huge<std::vector<T>> = T{2};


          You can check it with



          std::cout << huge<int> << std::endl;
          std::cout << huge<long> << std::endl;
          std::cout << huge<float> << std::endl;
          std::cout << huge<double> << std::endl;
          std::cout << huge<long double> << std::endl;
          std::cout << huge<std::vector<int>> << std::endl;





          share|improve this answer





















          • 1





            That might be as good as it gets, and I guess I could add another specialization with std::enable_if</*is vector*/> to restrict it to vector types.

            – ZachB
            Dec 31 '18 at 0:25











          • @ZachB - not sure to understand what do you want but... added specialization

            – max66
            Dec 31 '18 at 0:31











          • sorry, I meant that I could add a specialization with std::enable_if</* is Vec4f or Vec8f or VecXX... */>. I know how to do that, was just thinking out loud. Thanks!

            – ZachB
            Dec 31 '18 at 3:41













          • I've (hopefully) clarified the question and posted the specific solution so far, pointing out the remaining flaws, in case you have any ideas for improvements.

            – ZachB
            Dec 31 '18 at 9:29



















          0














          Leaving @max66's answer as the accepted one for the credit, but here's the specific solution I wound up with:



          struct _VectorTraits { static constexpr bool is_vector = true; };
          template<class T> struct VectorTraits : _VectorTraits { static constexpr bool is_vector = false; };
          template<> struct VectorTraits<Vec4f> : _VectorTraits { typedef float value_type; };
          template<> struct VectorTraits<Vec8f> : _VectorTraits { typedef float value_type; };
          template<> struct VectorTraits<Vec4d> : _VectorTraits { typedef double value_type; };

          template<typename T> using EnableIfFP = std::enable_if_t<std::is_floating_point<T>::value>;
          template<typename T> using EnableIfVec = std::enable_if_t<VectorTraits<T>::is_vector>;

          template<typename T> constexpr T EXP = std::numeric_limits<T>::max_exponent / 2;

          // Actual variable template, finally:
          template<typename T, typename Enabler = void> const T huge = T{ 0 };
          template<typename T> const T huge<T, EnableIfFP<T> > = std::scalbn(1, EXP<T>);
          template<typename T> const T huge<T, EnableIfVec<T> > = T{ huge<typename VectorTraits<T>::value_type> };


          This could still be improved I think:




          • It's verbose. T appears 4 times in each specialization's left-hand side.

          • Integral types (e.g. huge<uint32_t>) still compile with a nonsense 0 value. I'd rather them not compile.






          share|improve this answer























            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53982348%2fmultiple-variable-template-specializations-with-stdenable-if%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            2 Answers
            2






            active

            oldest

            votes








            2 Answers
            2






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            2














            Not exactly what you asked but I hope the following example can show you how to use SFINAE to specialize a template variable



            template <typename T, typename = void>
            constexpr T huge = T{0};

            template <typename T>
            constexpr T huge<T, std::enable_if_t<std::is_floating_point<T>{}>> = T{1};

            template <typename T>
            constexpr T huge<std::vector<T>> = T{2};


            You can check it with



            std::cout << huge<int> << std::endl;
            std::cout << huge<long> << std::endl;
            std::cout << huge<float> << std::endl;
            std::cout << huge<double> << std::endl;
            std::cout << huge<long double> << std::endl;
            std::cout << huge<std::vector<int>> << std::endl;





            share|improve this answer





















            • 1





              That might be as good as it gets, and I guess I could add another specialization with std::enable_if</*is vector*/> to restrict it to vector types.

              – ZachB
              Dec 31 '18 at 0:25











            • @ZachB - not sure to understand what do you want but... added specialization

              – max66
              Dec 31 '18 at 0:31











            • sorry, I meant that I could add a specialization with std::enable_if</* is Vec4f or Vec8f or VecXX... */>. I know how to do that, was just thinking out loud. Thanks!

              – ZachB
              Dec 31 '18 at 3:41













            • I've (hopefully) clarified the question and posted the specific solution so far, pointing out the remaining flaws, in case you have any ideas for improvements.

              – ZachB
              Dec 31 '18 at 9:29
















            2














            Not exactly what you asked but I hope the following example can show you how to use SFINAE to specialize a template variable



            template <typename T, typename = void>
            constexpr T huge = T{0};

            template <typename T>
            constexpr T huge<T, std::enable_if_t<std::is_floating_point<T>{}>> = T{1};

            template <typename T>
            constexpr T huge<std::vector<T>> = T{2};


            You can check it with



            std::cout << huge<int> << std::endl;
            std::cout << huge<long> << std::endl;
            std::cout << huge<float> << std::endl;
            std::cout << huge<double> << std::endl;
            std::cout << huge<long double> << std::endl;
            std::cout << huge<std::vector<int>> << std::endl;





            share|improve this answer





















            • 1





              That might be as good as it gets, and I guess I could add another specialization with std::enable_if</*is vector*/> to restrict it to vector types.

              – ZachB
              Dec 31 '18 at 0:25











            • @ZachB - not sure to understand what do you want but... added specialization

              – max66
              Dec 31 '18 at 0:31











            • sorry, I meant that I could add a specialization with std::enable_if</* is Vec4f or Vec8f or VecXX... */>. I know how to do that, was just thinking out loud. Thanks!

              – ZachB
              Dec 31 '18 at 3:41













            • I've (hopefully) clarified the question and posted the specific solution so far, pointing out the remaining flaws, in case you have any ideas for improvements.

              – ZachB
              Dec 31 '18 at 9:29














            2












            2








            2







            Not exactly what you asked but I hope the following example can show you how to use SFINAE to specialize a template variable



            template <typename T, typename = void>
            constexpr T huge = T{0};

            template <typename T>
            constexpr T huge<T, std::enable_if_t<std::is_floating_point<T>{}>> = T{1};

            template <typename T>
            constexpr T huge<std::vector<T>> = T{2};


            You can check it with



            std::cout << huge<int> << std::endl;
            std::cout << huge<long> << std::endl;
            std::cout << huge<float> << std::endl;
            std::cout << huge<double> << std::endl;
            std::cout << huge<long double> << std::endl;
            std::cout << huge<std::vector<int>> << std::endl;





            share|improve this answer















            Not exactly what you asked but I hope the following example can show you how to use SFINAE to specialize a template variable



            template <typename T, typename = void>
            constexpr T huge = T{0};

            template <typename T>
            constexpr T huge<T, std::enable_if_t<std::is_floating_point<T>{}>> = T{1};

            template <typename T>
            constexpr T huge<std::vector<T>> = T{2};


            You can check it with



            std::cout << huge<int> << std::endl;
            std::cout << huge<long> << std::endl;
            std::cout << huge<float> << std::endl;
            std::cout << huge<double> << std::endl;
            std::cout << huge<long double> << std::endl;
            std::cout << huge<std::vector<int>> << std::endl;






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Dec 31 '18 at 0:30

























            answered Dec 31 '18 at 0:05









            max66max66

            36.2k74165




            36.2k74165








            • 1





              That might be as good as it gets, and I guess I could add another specialization with std::enable_if</*is vector*/> to restrict it to vector types.

              – ZachB
              Dec 31 '18 at 0:25











            • @ZachB - not sure to understand what do you want but... added specialization

              – max66
              Dec 31 '18 at 0:31











            • sorry, I meant that I could add a specialization with std::enable_if</* is Vec4f or Vec8f or VecXX... */>. I know how to do that, was just thinking out loud. Thanks!

              – ZachB
              Dec 31 '18 at 3:41













            • I've (hopefully) clarified the question and posted the specific solution so far, pointing out the remaining flaws, in case you have any ideas for improvements.

              – ZachB
              Dec 31 '18 at 9:29














            • 1





              That might be as good as it gets, and I guess I could add another specialization with std::enable_if</*is vector*/> to restrict it to vector types.

              – ZachB
              Dec 31 '18 at 0:25











            • @ZachB - not sure to understand what do you want but... added specialization

              – max66
              Dec 31 '18 at 0:31











            • sorry, I meant that I could add a specialization with std::enable_if</* is Vec4f or Vec8f or VecXX... */>. I know how to do that, was just thinking out loud. Thanks!

              – ZachB
              Dec 31 '18 at 3:41













            • I've (hopefully) clarified the question and posted the specific solution so far, pointing out the remaining flaws, in case you have any ideas for improvements.

              – ZachB
              Dec 31 '18 at 9:29








            1




            1





            That might be as good as it gets, and I guess I could add another specialization with std::enable_if</*is vector*/> to restrict it to vector types.

            – ZachB
            Dec 31 '18 at 0:25





            That might be as good as it gets, and I guess I could add another specialization with std::enable_if</*is vector*/> to restrict it to vector types.

            – ZachB
            Dec 31 '18 at 0:25













            @ZachB - not sure to understand what do you want but... added specialization

            – max66
            Dec 31 '18 at 0:31





            @ZachB - not sure to understand what do you want but... added specialization

            – max66
            Dec 31 '18 at 0:31













            sorry, I meant that I could add a specialization with std::enable_if</* is Vec4f or Vec8f or VecXX... */>. I know how to do that, was just thinking out loud. Thanks!

            – ZachB
            Dec 31 '18 at 3:41







            sorry, I meant that I could add a specialization with std::enable_if</* is Vec4f or Vec8f or VecXX... */>. I know how to do that, was just thinking out loud. Thanks!

            – ZachB
            Dec 31 '18 at 3:41















            I've (hopefully) clarified the question and posted the specific solution so far, pointing out the remaining flaws, in case you have any ideas for improvements.

            – ZachB
            Dec 31 '18 at 9:29





            I've (hopefully) clarified the question and posted the specific solution so far, pointing out the remaining flaws, in case you have any ideas for improvements.

            – ZachB
            Dec 31 '18 at 9:29













            0














            Leaving @max66's answer as the accepted one for the credit, but here's the specific solution I wound up with:



            struct _VectorTraits { static constexpr bool is_vector = true; };
            template<class T> struct VectorTraits : _VectorTraits { static constexpr bool is_vector = false; };
            template<> struct VectorTraits<Vec4f> : _VectorTraits { typedef float value_type; };
            template<> struct VectorTraits<Vec8f> : _VectorTraits { typedef float value_type; };
            template<> struct VectorTraits<Vec4d> : _VectorTraits { typedef double value_type; };

            template<typename T> using EnableIfFP = std::enable_if_t<std::is_floating_point<T>::value>;
            template<typename T> using EnableIfVec = std::enable_if_t<VectorTraits<T>::is_vector>;

            template<typename T> constexpr T EXP = std::numeric_limits<T>::max_exponent / 2;

            // Actual variable template, finally:
            template<typename T, typename Enabler = void> const T huge = T{ 0 };
            template<typename T> const T huge<T, EnableIfFP<T> > = std::scalbn(1, EXP<T>);
            template<typename T> const T huge<T, EnableIfVec<T> > = T{ huge<typename VectorTraits<T>::value_type> };


            This could still be improved I think:




            • It's verbose. T appears 4 times in each specialization's left-hand side.

            • Integral types (e.g. huge<uint32_t>) still compile with a nonsense 0 value. I'd rather them not compile.






            share|improve this answer




























              0














              Leaving @max66's answer as the accepted one for the credit, but here's the specific solution I wound up with:



              struct _VectorTraits { static constexpr bool is_vector = true; };
              template<class T> struct VectorTraits : _VectorTraits { static constexpr bool is_vector = false; };
              template<> struct VectorTraits<Vec4f> : _VectorTraits { typedef float value_type; };
              template<> struct VectorTraits<Vec8f> : _VectorTraits { typedef float value_type; };
              template<> struct VectorTraits<Vec4d> : _VectorTraits { typedef double value_type; };

              template<typename T> using EnableIfFP = std::enable_if_t<std::is_floating_point<T>::value>;
              template<typename T> using EnableIfVec = std::enable_if_t<VectorTraits<T>::is_vector>;

              template<typename T> constexpr T EXP = std::numeric_limits<T>::max_exponent / 2;

              // Actual variable template, finally:
              template<typename T, typename Enabler = void> const T huge = T{ 0 };
              template<typename T> const T huge<T, EnableIfFP<T> > = std::scalbn(1, EXP<T>);
              template<typename T> const T huge<T, EnableIfVec<T> > = T{ huge<typename VectorTraits<T>::value_type> };


              This could still be improved I think:




              • It's verbose. T appears 4 times in each specialization's left-hand side.

              • Integral types (e.g. huge<uint32_t>) still compile with a nonsense 0 value. I'd rather them not compile.






              share|improve this answer


























                0












                0








                0







                Leaving @max66's answer as the accepted one for the credit, but here's the specific solution I wound up with:



                struct _VectorTraits { static constexpr bool is_vector = true; };
                template<class T> struct VectorTraits : _VectorTraits { static constexpr bool is_vector = false; };
                template<> struct VectorTraits<Vec4f> : _VectorTraits { typedef float value_type; };
                template<> struct VectorTraits<Vec8f> : _VectorTraits { typedef float value_type; };
                template<> struct VectorTraits<Vec4d> : _VectorTraits { typedef double value_type; };

                template<typename T> using EnableIfFP = std::enable_if_t<std::is_floating_point<T>::value>;
                template<typename T> using EnableIfVec = std::enable_if_t<VectorTraits<T>::is_vector>;

                template<typename T> constexpr T EXP = std::numeric_limits<T>::max_exponent / 2;

                // Actual variable template, finally:
                template<typename T, typename Enabler = void> const T huge = T{ 0 };
                template<typename T> const T huge<T, EnableIfFP<T> > = std::scalbn(1, EXP<T>);
                template<typename T> const T huge<T, EnableIfVec<T> > = T{ huge<typename VectorTraits<T>::value_type> };


                This could still be improved I think:




                • It's verbose. T appears 4 times in each specialization's left-hand side.

                • Integral types (e.g. huge<uint32_t>) still compile with a nonsense 0 value. I'd rather them not compile.






                share|improve this answer













                Leaving @max66's answer as the accepted one for the credit, but here's the specific solution I wound up with:



                struct _VectorTraits { static constexpr bool is_vector = true; };
                template<class T> struct VectorTraits : _VectorTraits { static constexpr bool is_vector = false; };
                template<> struct VectorTraits<Vec4f> : _VectorTraits { typedef float value_type; };
                template<> struct VectorTraits<Vec8f> : _VectorTraits { typedef float value_type; };
                template<> struct VectorTraits<Vec4d> : _VectorTraits { typedef double value_type; };

                template<typename T> using EnableIfFP = std::enable_if_t<std::is_floating_point<T>::value>;
                template<typename T> using EnableIfVec = std::enable_if_t<VectorTraits<T>::is_vector>;

                template<typename T> constexpr T EXP = std::numeric_limits<T>::max_exponent / 2;

                // Actual variable template, finally:
                template<typename T, typename Enabler = void> const T huge = T{ 0 };
                template<typename T> const T huge<T, EnableIfFP<T> > = std::scalbn(1, EXP<T>);
                template<typename T> const T huge<T, EnableIfVec<T> > = T{ huge<typename VectorTraits<T>::value_type> };


                This could still be improved I think:




                • It's verbose. T appears 4 times in each specialization's left-hand side.

                • Integral types (e.g. huge<uint32_t>) still compile with a nonsense 0 value. I'd rather them not compile.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Dec 31 '18 at 9:27









                ZachBZachB

                5,31413159




                5,31413159






























                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53982348%2fmultiple-variable-template-specializations-with-stdenable-if%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Monofisismo

                    Angular Downloading a file using contenturl with Basic Authentication

                    Olmecas