Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6878875
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 27, 20262026-05-27T04:46:39+00:00 2026-05-27T04:46:39+00:00

I’m writing a template function which should swap two elements of a boost::mpl::vector (similarly

  • 0

I’m writing a template function which should swap two elements of a boost::mpl::vector (similarly to std::swap). The difficult part is there is no concept of a variable during compile time. I have written a draft but I wonder if there are better ways to approach this.

My current code sketch extracts an integral index from iterators and performs a copy of the sequence type with the elements swapped. The question is – can this be done better:

#include <boost/mpl/distance.hpp>
#include <boost/mpl/begin_end.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/comparison.hpp>
#include <boost/mpl/equal.hpp>
#include <boost/mpl/clear.hpp>
#include <boost/mpl/next_prior.hpp>
#include <boost/mpl/push_back.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/or.hpp>

using boost::mpl::distance;
using boost::mpl::begin;
using boost::mpl::end;
using boost::mpl::next;
using boost::mpl::at;
using boost::mpl::or_;
using boost::mpl::int_;
using boost::mpl::eval_if;
using boost::mpl::greater;
using boost::mpl::equal;
using boost::mpl::clear;
using boost::mpl::push_back;


namespace boost { namespace mpl {

template<template<typename, typename> class T, class A, class B>
struct eval2 {
    typedef typename T<typename A::type, typename B::type>::type type;
};


namespace details {

    template <typename Dest_seq, typename It_end, typename It_first, typename It_second, typename It_idx>
    struct copy_and_swap {
    private:
        typedef typename eval_if< is_same<It_idx, It_first>,
                                  eval2<push_back, Dest_seq, deref<It_second> >,
                                  eval_if<is_same<It_idx, It_second>,
                                          eval2<push_back, Dest_seq, deref<It_first> >,
                                          eval2<push_back, Dest_seq, deref<It_idx> >
                                         >
                                >::type Limit_idx;
        typedef typename next<It_idx>::type it_idx_next;

    public:
        // next step
        typedef typename eval_if <is_same<it_idx_next, It_end>,
                                  New_seq,
                                  copy_and_swap<New_seq, 
                                                It_end, 
                                                It_first, 
                                                It_second, 
                                                it_idx_next>
                                 >::type type;
    };

} // namespace details


template<typename Seq, typename Begin, typename End>
struct swap {
  private:
    typedef typename begin<Seq>::type                it_begin;
    typedef typename end<Seq>::type                  it_end;
    // get an empty container type "compatible" with Seq
    typedef typename clear<Seq>::type        Container_t;
    // border case - swap self
    typedef typename is_same<Begin, End>::type   swap_self;
    // border case - less than 2 elements in sequence
    typedef typename less<size<Seq>, int_<2> >::type    no_swap;

  public:
    // perform the element swapping
    typedef typename eval_if <or_<swap_self, no_swap>,
                              Seq,
                              details::copy_and_swap<Container_t,
                                                     it_end,
                                                     Begin,
                                                     End,
                                                     it_begin >
                             >::type type;
};

} // namespace mpl
} // namespace boost

This metafunction can be used like:

struct value_printer {
    template< typename U > void operator()(U x) {
        std::cout << x << ',';
    }
};



typedef vector_c<int, 1, 2, 3, 6, 5, 4>::type    test_vect;
typedef begin<test_vect>::type    it_beg;
typedef advance<it_beg, int_<2> >::type    it;
typedef advance<it_beg, int_<5> >::type    it_stop;
typedef m_swap<test_vect, it_stop, it>::type    result;
boost::mpl::for_each< result >( value_printer() );

and the result is 1,2,4,6,5,3,

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-27T04:46:40+00:00Added an answer on May 27, 2026 at 4:46 am

    Here is a solution using only MPL metafunctions, without explicit recursion. The idea is to start by copying all the values between the beginning of the sequence and the first value to swap, insert the second value, copy the middle, insert the first value, and finally copy the end.

    A disadvantage of this method is that the iterators must form a valid range: Second must not be before First. I don’t think there is any way to overcome this restriction with this solution, but it does not seem like an unbearable requirement.

    Here is the code:

    // Precondition: [First, Second] is a valid range in Seq
    template< typename Seq, typename First, typename Second >
    struct swap {
      private:
        typedef typename begin< Seq >::type begin;
        typedef typename end< Seq >::type   end;
    
        typedef typename clear< Seq >::type empty_container;
    
        // Insert values from begin to first
        typedef typename
            copy<
                iterator_range< begin, First >,
                back_inserter< empty_container >
            >::type prefix;
    
        // Insert second value 
        typedef typename
            push_back<
                prefix, typename
                deref< Second >::type
            >:: type prefixSecond;
    
        // Insert values from first+1 to second
        typedef typename
            copy<
                iterator_range< typename next< First >::type, Second >,
                back_inserter< prefixSecond >
            >::type prefixSecondMiddle;
    
        // Insert first value
        typedef typename
            push_back<
                prefixSecondMiddle, typename
                deref< First >::type
            >::type prefixSecondMiddleFirst;
    
        // Insert values from second+1 to end
        typedef typename
            copy<
                iterator_range< typename next< Second >::type, end >,
                back_inserter< prefixSecondMiddleFirst >
            >::type prefixSecondMiddleFirstSuffix;
    
      public:
        typedef prefixSecondMiddleFirstSuffix type;
    };
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a string like this: La Torre Eiffel paragonata all&#8217;Everest What PHP function
link Im having trouble converting the html entites into html characters, (&# 8217;) i
I am trying to understand how to use SyndicationItem to display feed which is
I used javascript for loading a picture on my website depending on which small
I would like to run a str_replace or preg_replace which looks for certain words
I'm parsing an RSS feed that has an &#8217; in it. SimpleXML turns this
I have a text area in my form which accepts all possible characters from
I need a function that will clean a strings' special characters. I do NOT
I want to construct a data frame in an Rcpp function, but when I
I am writing an app with both english and french support. The app requests

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.